go并发任务超时控制

1310阅读 0评论2020-04-13 nuoyazhou110
分类:Web开发


点击(此处)折叠或打开

  1. package main

  2. import "fmt"
  3. import "sync"
  4. import "time"
  5. import "context"
  6. import "math/rand"
  7. func work(ctx context.Context) {
  8.    resultChan := make(chan int,1)
  9.    var wg sync.WaitGroup
  10.    wg.Add(1)
  11.    defer wg.Wait()
  12.    go func() {
  13.      defer func(){
  14.          recover()
  15.      }()
  16.      defer close(resultChan)
  17.      r := rand.New(rand.NewSource(time.Now().UnixNano()))
  18.      num := r.Intn(3)
  19.      time.Sleep(time.Duration(num)*time.Second)
  20.      fmt.Printf("任务执行了%d s \n",num)

  21.      resultChan <- 1
  22.      wg.Done()
  23.    }()
  24.    select{
  25.      case <-ctx.Done():
  26.         fmt.Println("超时结束")
  27.      case <-resultChan:
  28.         fmt.Println("正常结束")
  29.    }
  30. }
  31. func main() {
  32.   ctx,cancel := context.WithTimeout(context.Background(),time.Second*2)
  33.   defer cancel()
  34.   work(ctx)
  35. }

此处实现了超时控制,但是超时后无法立即终止超时的go协程.
考虑在任务中添加

点击(此处)折叠或打开

  1. time.AfterFunc(2*time.Second,func() {
  2.        //退出协程
  3.        fmt.Println("超时了...")
  4.        runtime.Goexit()
  5.      })
通过该处来控制 go协程退出,实验发现该处为异步调用,退出的非当前的go协程.

在一个协程中无法直接停止另一个协程的执行,只能等待超时的协程自己执行结束.


上一篇:python3.4中asyncio
下一篇:go普通指针unsafe.Pointer uintptr互相转换