Golang WaitGroup超时错误处理

Golang WaitGroup超时错误处理,go,Go,在下面的代码中,如果一个启动的go例程需要太长时间(例如>10秒)才能完成,我如何添加正确的超时错误处理?请注意,我不希望有一个“总体”超时,而是希望每个go例程都有一个超时,这样我还可以在错误报告中知道哪个go例程超时 var wg sync.WaitGroup for _, element:= range elements{ wg.Add(1) go doWork(element, &wg) } wg.Wait() 善意的问候好的方法是使用上下文。截止日期: 主程

在下面的代码中,如果一个启动的go例程需要太长时间(例如>10秒)才能完成,我如何添加正确的超时错误处理?请注意,我不希望有一个“总体”超时,而是希望每个go例程都有一个超时,这样我还可以在错误报告中知道哪个go例程超时

var wg sync.WaitGroup

for _, element:= range elements{
    wg.Add(1)
    go doWork(element, &wg)
}
wg.Wait()

善意的问候

好的方法是使用
上下文。截止日期

主程序包
进口(
“上下文”
“fmt”
“时间”
)
func main(){
ctx,cancel:=context.WithDeadline(context.Background(),time.Now().Add(100*time.毫秒))
//尽管ctx将过期,但将其命名为
//任何情况下的取消功能。如果不这样做,可能会保留
//上下文及其父级的活动时间超过了必要的时间。
推迟取消
挑选{
case您可以通过以下方式使用:

func doWork(ctx context.Context, element Element, wg &sync.WaitGroup) {
    defer wg.Done()

    done := make(chan struct{})
    go func() {
       // do some work on element
       done <- struct{}{} // signal work is done
    }

    select {
       case <- done: 
       { 
          // work completed in time
       }
       case <- ctx.Done:
       {
         // timeout reached
       }
    }
}

contexts := make([]*context.Context, len(elements))

for _, element:= range elements{
    wg.Add(1)
    ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
    defer cancel()
    contexts = append(contexts, ctx)
    go doWork(ctx, element, &wg)
}
wg.Wait()

for i, ctx := range contexts {
  if ctx.Err() {
     fmt.Println("Go routine ", i, "canceled due to", ctx.Err())
  }
}
func-doWork(ctx-context.context,element-element,wg&sync.WaitGroup){
推迟工作组完成()
完成:=make(chan结构{})
go func(){
//在元素上做一些工作

完成我确实有同样的问题,并提出了这种方法:

使用:
context.WithTimeout(context.Background(),10*time.Second)

不知道这是否是正确的方法,但是否有效:

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

func doWork(element int, wg *sync.WaitGroup) {
    ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(10*time.Second))
    defer cancel()

    ch := make(chan struct{})

    go func() {
        time.Sleep(time.Second)
        fmt.Printf("element = %+v\n", element)
        ch <- struct{}{}
    }()

    select {
    case <-ch:
    case <-ctx.Done():
        fmt.Println(ctx.Err())
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup

    elements := []int{1, 2, 3}

    for _, element := range elements {
        wg.Add(1)
        go doWork(element, &wg)
    }
    wg.Wait()
}

这是我不知道是否是最好的方法的一部分,但似乎是主要在想处理
ctx.Done()

时使用上下文时要遵循的模式。context.WithDeadline调用可以简化为
context.WithTimeout(context.Background(),10*time.Second)
.context.WithDudate调用可以简化为context.WithTimeout(context.Background(),100*time.毫秒)@Peter:
WithTimeout
本身调用
WithDudate
请参见内部:
func WithTimeout(父上下文,timeout.Duration)(context,CancelFunc){返回WithDudate(父,time.Now().Add(timeout))}
func doWork(ctx context.Context, element Element, wg &sync.WaitGroup) {
    defer wg.Done()

    done := make(chan struct{})
    go func() {
       // do some work on element
       done <- struct{}{} // signal work is done
    }

    select {
       case <- done: 
       { 
          // work completed in time
       }
       case <- ctx.Done:
       {
         // timeout reached
       }
    }
}

contexts := make([]*context.Context, len(elements))

for _, element:= range elements{
    wg.Add(1)
    ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
    defer cancel()
    contexts = append(contexts, ctx)
    go doWork(ctx, element, &wg)
}
wg.Wait()

for i, ctx := range contexts {
  if ctx.Err() {
     fmt.Println("Go routine ", i, "canceled due to", ctx.Err())
  }
}
package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

func doWork(element int, wg *sync.WaitGroup) {
    ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(10*time.Second))
    defer cancel()

    ch := make(chan struct{})

    go func() {
        time.Sleep(time.Second)
        fmt.Printf("element = %+v\n", element)
        ch <- struct{}{}
    }()

    select {
    case <-ch:
    case <-ctx.Done():
        fmt.Println(ctx.Err())
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup

    elements := []int{1, 2, 3}

    for _, element := range elements {
        wg.Add(1)
        go doWork(element, &wg)
    }
    wg.Wait()
}
go func(ch chan struct{}) {
   // your code logic goes here
}(ch)