Better late than never.

golang 的简单并发控制

一、sync + chan

1、定义 sync.waitgroup、make 一个channel

var (
  wg sync.WaitGroup
)

ch := make(chan int,2) // 定义2个缓冲区的channel,一般为你的并发数

2、对程序的执行加上 WaitGroup 与 channel 的控制

// 每遍历一次就使用wg.Add()记录标记一次

for i:=0;i<10;i++ {
    wg.Add(1)
}

// 程序每执行一次(goroutine)就往channel中写入一次
ch <- 1 // 将1写入管道中

.... 执行程序

// 程序执行完毕 从channel 中取出执行前写入管道中的数据、并且标记wg.Done()

<-ch
wg.Done()

// 此时最外层 wg.Wait 在等待主程序的完成

wg.Wait()
e.g
func main() {
    ch := make(chan int, 2)

    count := 10

    for i := 1; i <= count; i++ {
        wg.Add(1)

        go func(i int) {
            ch <- i

            c := i + 1
            // 模拟主程序执行处理时间
            time.Sleep(time.Second)

            d := <-ch
            wg.Done()

            log.Printf("%d + 1  = %d ,chan= %d ", i, c, d)

        }(i)
    }

    wg.Wait()
}

二、ants

开源,来自 https://github.com/panjf2000/ants

简单使用三部曲

1、定义一个协程池,大小为需要控制的并发数
pool, _ := ants.NewPool(2)

2、提交任务
pool.Submit()

3、释放协程池
ants.Release()

ps: 一样需要sync.WaitGroup 的协助,用法 sync + chan 的方式一样

e.g
func main() {
    // 用完协程池释放
    defer ants.Release()
    // 定义一个协程池
    pool, _ := ants.NewPool(2)

    count := 10

    for i := 1; i <= count; i++ {
        wg.Add(1)

        // goroutine 前需要重新赋值i => _i
        _i := i

        task := func() {
            c := _i + 1
            log.Printf("%d + 1  = %d", _i, c)
            time.Sleep(time.Second * 1)
        }

        // 提交任务
        pool.Submit(func() {
            task()
            wg.Done()
        })
    }

    wg.Wait()

    log.Println("执行完毕")
}

-- END

写的不错,赞助一下主机费

扫一扫,用支付宝赞赏
扫一扫,用微信赞赏

暂无评论~~