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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM