在Go语言中,sync.Work
是一个并发安全的队列,用于在多个goroutine之间传递任务。它提供了一种简单的方式来将任务分配给多个goroutine并行执行,并确保任务按照一定的顺序完成。
sync.Work
类型定义如下:
go复制代码
type Work struct { mu Mutex job int64 done chan struct{} f func(context.Context, int64) error }
sync.Work`结构体包含以下字段:
mu
:一个互斥锁(Mutex),用于保护并发访问。job
:一个int64类型的字段,用于表示当前正在执行的任务编号。done
:一个无缓冲的通道(chan),用于通知任务完成。当任务完成时,会向该通道发送一个信号。f
:一个函数类型,用于定义任务的执行逻辑。该函数接受一个context.Context
和任务编号作为参数,并返回一个错误。
使用sync.Work
来分配任务的步骤如下:
创建一个
sync.Work
实例。定义一个函数类型,该函数类型与
sync.Work.f
字段的类型匹配。在需要执行任务的goroutine中,调用
Work.Add()
方法将任务添加到队列中。这会触发任务的执行。在任务的执行函数中,使用
Work.Done()
方法来表示任务已经完成。这会触发后续任务的执行。
下面是一个使用sync.Work
的示例代码:
package main
import ( "context" "fmt" "sync" )
func worker(ctx context.Context, id int64) error { fmt.Printf("Starting worker %d\n", id) // 模拟任务的执行时间 // 这里可以替换为实际的任务逻辑 for { select { case <-ctx.Done(): return ctx.Err() default: // 执行任务逻辑... fmt.Printf("Worker %d is working...\n", id) // 模拟任务完成,耗时1秒 // 这里可以替换为实际的任务完成逻辑 if err := <-ctx.Done(); err != nil { return err } fmt.Printf("Worker %d is done.\n", id) return nil } } }
func main() { var wg sync.WaitGroup w := sync.Work{f: worker} // 创建Work实例,定义任务执行函数worker wg.Add(1) // 启动一个goroutine来执行任务并监听完成通知 go func() { defer wg.Done() // 任务完成后通知WaitGroup计数减1 for i := int64(1); i <= 5; i++ { // 添加5个任务到队列中,编号从1到5递增 w.Add(i) // 将任务添加到队列中,触发任务的执行 time.Sleep(time.Second) // 模拟任务的执行时间,这里可以根据实际需求调整时间间隔或使用其他方式触发任务执行(如监听信号、监听事件等) } w.Done() // 所有任务完成后通知完成通知的goroutine退出(阻塞等待) }() wg.Wait() //