介绍

使用无缓冲的通道来创建一个 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()
}

执行结果

// :: goroutineID:,打印名字为:lili
// :: goroutineID:,打印名字为:yingying
// :: goroutineID:,打印名字为:yingying
// :: goroutineID:,打印名字为:yingying
// :: goroutineID:,打印名字为:lili
// :: goroutineID:,打印名字为:lili
// :: goroutineID:,打印名字为:yingying
// :: goroutineID:,打印名字为:yingying
// :: goroutineID:,打印名字为:lili
// :: goroutineID:,打印名字为:yingying
// :: goroutineID:,打印名字为:lili
// :: goroutineID:,打印名字为:lili
// :: goroutineID:,打印名字为:lili
// :: goroutineID:,打印名字为:yingying
// :: goroutineID:,打印名字为:yingying
// :: goroutineID:,打印名字为:lili
// :: goroutineID:,打印名字为:yingying
// :: goroutineID:,打印名字为:lili
// :: goroutineID:,打印名字为:lili
// :: goroutineID:,打印名字为:yingying

Go语言-并发模式-goroutine池实例(work)的更多相关文章

  1. Go语言-并发模式-资源池实例(pool)

    Go语言并发模式 利用goroutine和channel进行go的并发模式,实现一个资源池实例(<Go语言实战>书中实例稍作修改) 资源池可以存储一定数量的资源,用户程序从资源池获取资源进 ...

  2. go语言】Goroutines 并发模式

    并发模式 让我们先来回顾一下boring函数的例子. func boring(msg string, c chan string) {    for i := 0; ; i++ {         c ...

  3. WCF实例上下文模式与并发模式对性能的影响

    实例上下文模式 InstanceContextMode 控制在响应客户端调用时,如何分配服务实例.InstanceContextMode 可以设置为以下值: •Single – 为所有客户端调用分配一 ...

  4. 《Go语言实战》摘录:7.2 并发模式 - pool

    7.2 并发模式 - pool

  5. 《Go语言实战》摘录:7.3 并发模式 - work

    7.3 并发模式 - work

  6. 《Go语言实战》摘录:7.1 并发模式 - runner

    7.1 并发模式 - runner

  7. 09. Go 语言并发

    Go 语言并发 并发指在同一时间内可以执行多个任务.并发编程含义比较广泛,包含多线程编程.多进程编程及分布式程序等.本章讲解的并发含义属于多线程编程. Go 语言通过编译器运行时(runtime),从 ...

  8. Go并发模式:管道与取消

    关键字:Go语言,管道,取消机制,并发,sync.WaitGroup,包引用,通道,defer,select GO并发模式:管道与取消 简介 Go的并发能力可以使构建一个流数据管道变得非常容易,并且可 ...

  9. Go语言并发机制

    Go语言中的并发 使用goroutine编程 使用 go 关键字用来创建 goroutine .将go声明放到一个需调用的函数之前,在相同地址空间调用运行这个函数,这样该函数执行时便会作为一个独立的并 ...

随机推荐

  1. NirSoft 实用程序

    64-bit (x64) utilities package 此软件包包含NirSoft中的所有实用程序,这些实用程序具有64位版本(x64)Windows的独立构建. 此程序包包含下面列表中每个实用 ...

  2. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-signal

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  3. Git如何将本地test分支设置跟踪origin/test分支

    前提条件: 有一个远程仓库其中只有一个master分支,然后我把它clone到本地 1.新建一个本地分支test, 2.然后把它push到远程仓库(git push origin test) 3.本地 ...

  4. 2020/2/21 fiyocms代码审计

    0x00 前言 上午上了网课,一上午就装好了cms,下午还有网课,要是结束的早就进行审计. 解决了一下phpstudy使用过程中: Forbidden You don't have permissio ...

  5. 小程序中的web-view与h5网页之间的交互

    官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/web-view.html web-view 基础库 1.6.4 开始支 ...

  6. 配置tomcat、nginx实现反向代理(需操作)

    配置tomcat.nginx实现反向代理现在我想通过nginx访问tomcat 这就要我们去修改nginx的核心配置文件,在其目录下的conf文件夹下的nginx.conf文件,那么首先我们就要了解该 ...

  7. go语言开发环境安装及第一个go程序

    下载Go语言开发包 大家可以在Go语言官网(https://golang.google.cn/dl/)下载 Windows 系统下的Go语言开发包,如下图所示. 安装Go语言开发包 双击我们下载好的G ...

  8. 058-PHP中goto语句的使用

    <?php for($i=1;$i<=5;$i++){ //使用for循环循环输出1~5 if($i==3) goto ECH; //当$i为3时候跳出for循环 echo "$ ...

  9. 二、【重点】环境安装:通过淘宝 cnpm 快速安装使用 React,生成项目,运行项目、安装项目

    1.cnpm代替npm 如果你的系统还不支持 Node.js 及 NPM 可以参考我们的 Node.js 教程. 我们建议在 React 中使用 CommonJS 模块系统,比如 browserify ...

  10. PyCharm下创建并运行我们的第一个Django项目

    PyCharm下创建并运行我们的第一个Django项目 准备工作: 假设读者已经安装好python 2x或3x,以及安装好Django,以及Pycharm 1. 创建一个新的工程 第一次运行Pycha ...