当前位置: 技术文章>> go中的work详细介绍与代码示例

文章标题:go中的work详细介绍与代码示例
  • 文章分类: 后端
  • 10781 阅读
文章标签: go go基础

在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来分配任务的步骤如下:

  1. 创建一个sync.Work实例。

  2. 定义一个函数类型,该函数类型与sync.Work.f字段的类型匹配。

  3. 在需要执行任务的goroutine中,调用Work.Add()方法将任务添加到队列中。这会触发任务的执行。

  4. 在任务的执行函数中,使用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() //


推荐文章