Go语言-并发模式-goroutine池实例(work)

介绍

使用无缓冲的通道来创建一个 goroutine 池,这些 goroutine 执行并控制一组工作,让其并发执行。在这种情况下,使用无缓冲的通道要比随意指定一个缓冲区大小的有缓冲的通道好,因为这个情况下既不需要一个工作队列,也不需要一组 goroutine 配合执行。这种使用无缓冲的通道的方法允许使用者知道什么时候 goroutine 池正在执行工作,而且如果池里的所有goroutine 都忙,无法接受新的工作的时候,也能及时通过通道来通知调用者。使用无缓冲的通道不会有工作在队列里丢失或者卡住,所有工作都会被处理。

程序

work.go

package work

import (
    "sync"
)

//任务类型接口
type Worker interface {
    Task(goid int)
}

//任务池
type Pool struct {
    work chan Worker
    wg   sync.WaitGroup
}

//新建
func New(maxGoroutines int) *Pool {
    //任务池
    p := Pool{
        work: make(chan Worker),
    }
    p.wg.Add(maxGoroutines)
    //创建maxGoroutines个go协程
    for i := 0; i < maxGoroutines; i++ {
        go func(goid int) {
            //保证goroutine不停止执行通道中的任务
            for w := range p.work {
                w.Task(goid)
            }
            //每个goroutine不再执行work通道中任务时停止
            p.wg.Done()
        }(i)
    }
    return &p
}

//运行
func (p *Pool) Run(r Worker) {
    p.work <- r
}

//停止
func (p *Pool) Shutdown() {
    close(p.work)
    p.wg.Wait()
}

main.go

package main

import (
    "gopro/patterns/work"
    "log"
    "sync"
    "time"
)

//
var names = []string{
    "lili",
    "yingying",
}

//Worker实现类型
type namePrinter struct {
    name string
}

func (n *namePrinter) Task(goid int) {
    log.Printf("goroutineID:%d,打印名字为:%s\n", goid, n.name)
    time.Sleep(time.Second)
}

func main() {
    p := work.New(3)
    var wg sync.WaitGroup
    wg.Add(10 * len(names))

    for i := 0; i < 10; i++ {
        for _, name := range names {
            //任务实例
            np := namePrinter{
                name: name,
            }

            go func() {
                p.Run(&np)
                wg.Done()
            }()
        }
    }
    wg.Wait()
    p.Shutdown()
}

执行结果

2019/06/22 22:55:44 goroutineID:1,打印名字为:lili
2019/06/22 22:55:44 goroutineID:0,打印名字为:yingying
2019/06/22 22:55:44 goroutineID:2,打印名字为:yingying
2019/06/22 22:55:45 goroutineID:0,打印名字为:yingying
2019/06/22 22:55:45 goroutineID:2,打印名字为:lili
2019/06/22 22:55:45 goroutineID:1,打印名字为:lili
2019/06/22 22:55:46 goroutineID:0,打印名字为:yingying
2019/06/22 22:55:46 goroutineID:2,打印名字为:yingying
2019/06/22 22:55:46 goroutineID:1,打印名字为:lili
2019/06/22 22:55:47 goroutineID:2,打印名字为:yingying
2019/06/22 22:55:47 goroutineID:1,打印名字为:lili
2019/06/22 22:55:47 goroutineID:0,打印名字为:lili
2019/06/22 22:55:48 goroutineID:1,打印名字为:lili
2019/06/22 22:55:48 goroutineID:0,打印名字为:yingying
2019/06/22 22:55:48 goroutineID:2,打印名字为:yingying
2019/06/22 22:55:49 goroutineID:2,打印名字为:lili
2019/06/22 22:55:49 goroutineID:0,打印名字为:yingying
2019/06/22 22:55:49 goroutineID:1,打印名字为:lili
2019/06/22 22:55:50 goroutineID:0,打印名字为:lili
2019/06/22 22:55:50 goroutineID:1,打印名字为:yingying

猜你喜欢

转载自www.cnblogs.com/limaosheng/p/11070819.html