golang 裸写一个pool池控制协程的大小
这几天深入的研究了一下golang 的协程,读了一个好文
http://mp.weixin.qq.com/s?__biz=MjM5OTcxMzE0MQ==&mid=2653369770&idx=1&sn=044be64c577a11a9a13447b373e80082&chksm=bce4d5b08b935ca6ad59abb5cc733a341a5126fefc0e6600bd61c959969c5f77c95fbfb909e3&mpshare=1&scene=1&srcid=1010dpu0DlPHi6y1YmrixifX#rd
就想拿来练手,深入理解了一下,如何控制,协程的大小具体代码如下:
package main import (
"fmt"
"strconv"
"time"
"math/rand"
) //声明成游戏
type Payload struct {
name string
}
//打游戏
func (p *Payload) Play() {
fmt.Printf("%s 打LOL游戏...当前任务完成\n",p.name)
} //任务
type Job struct {
Payload Payload
}
//任务队列
var JobQueue chan Job // 工人
type Worker struct {
name string //工人的名字
// WorkerPool chan JobQueue //对象池
WorkerPool chan chan Job//对象池
JobChannel chan Job //通道里面拿
quit chan bool //
} // 新建一个工人
func NewWorker(workerPool chan chan Job,name string) Worker{ fmt.Printf("创建了一个工人,它的名字是:%s \n",name);
return Worker{
name:name,//工人的名字
WorkerPool: workerPool, //工人在哪个对象池里工作,可以理解成部门
JobChannel:make(chan Job),//工人的任务
quit:make(chan bool),
}
} // 工人开始工作 func (w *Worker) Start(){
//开一个新的协程
go func(){
for{
//注册到对象池中,
w.WorkerPool <-w.JobChannel
fmt.Printf("[%s]把自己注册到 对象池中 \n",w.name)
select {
//接收到了新的任务
case job :=<- w.JobChannel:
fmt.Printf("[%s] 工人接收到了任务 当前任务的长度是[%d]\n",w.name,len(w.WorkerPool))
job.Payload.Play()
time.Sleep(time.Duration(rand.Int31n(1000)) * time.Millisecond)
//接收到了任务
case <-w.quit:
return
}
}
}()
} func (w Worker) Stop(){
go func(){
w.quit <- true
}()
} type Dispatcher struct {
//WorkerPool chan JobQueue
name string //调度的名字
maxWorkers int //获取 调试的大小
WorkerPool chan chan Job //注册和工人一样的通道
} func NewDispatcher(maxWorkers int) *Dispatcher {
pool :=make(chan chan Job,maxWorkers)
return &Dispatcher{
WorkerPool:pool,// 将工人放到一个池中,可以理解成一个部门中
name:"调度者",//调度者的名字
maxWorkers:maxWorkers,//这个调度者有好多个工人
}
} func (d *Dispatcher) Run(){
// 开始运行
for i :=0;i<d.maxWorkers;i++{
worker := NewWorker(d.WorkerPool,fmt.Sprintf("work-%s",strconv.Itoa(i)))
//开始工作
worker.Start()
}
//监控
go d.dispatch() } func (d *Dispatcher) dispatch() {
for {
select {
case job :=<-JobQueue:
fmt.Println("调度者,接收到一个工作任务")
time.Sleep(time.Duration(rand.Int31n(1000)) * time.Millisecond)
// 调度者接收到一个工作任务
go func (job Job) {
//从现有的对象池中拿出一个
jobChannel := <-d.WorkerPool jobChannel <- job }(job)
default: //fmt.Println("ok!!")
} }
} func initialize() {
maxWorkers := 2;
maxQueue := 4;
//初始化一个调试者,并指定它可以操作的 工人个数
dispatch := NewDispatcher(maxWorkers)
JobQueue =make(chan Job,maxQueue) //指定任务的队列长度
//并让它一直接运行
dispatch.Run()
} func main() {
//初始化对象池
initialize()
for i:=0;i<10;i++{
p := Payload{
fmt.Sprintf("玩家-[%s]",strconv.Itoa(i)),
}
JobQueue <- Job{
Payload:p,
}
time.Sleep(time.Second)
}
close(JobQueue)
}
其实,他的大概思路就是,好比你在一家公司里,你们ceo(main)给你的领导(dispatcher)分配任务,你的领导(dispatcher)再把任务分配给你(worker),你再去执行具体的任务(playload),我理解了好一会,才明白,上面就是一个模子,可以直接复制就可以用
其中一直不明白
var JobQueue chan chan Job
这个是啥意思,后面在群里问了下,瞬间我就明白了,其实通道的通道,还是通道
golang 裸写一个pool池控制协程的大小的更多相关文章
- 死磕 java线程系列之自己动手写一个线程池
欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. (手机横屏看源码更方便) 问题 (1)自己动手写一个线程池需要考虑哪些因素? (2)自己动手写 ...
- 手写一个线程池,带你学习ThreadPoolExecutor线程池实现原理
摘要:从手写线程池开始,逐步的分析这些代码在Java的线程池中是如何实现的. 本文分享自华为云社区<手写线程池,对照学习ThreadPoolExecutor线程池实现原理!>,作者:小傅哥 ...
- python-进程池与线程池,协程
一.进程池与线程池 实现并发的手段有两种,多线程和多进程.注:并发是指多个任务看起来是同时运行的.主要是切换+保存状态. 当我们需要执行的并发任务大于cpu的核数时,我们需要知道一个操作系统不能无限的 ...
- 并发编程(六)——进程/线程池、协程、gevent第三方库
进程/线程池.协程.gevent第三方库 一.进程/线程池 1.进程池 (1)什么是进程池 如果需要创建的子进程数量不大,可以直接利用multiprocess中的Process来创建.但是当需要创建上 ...
- 进程池与线程池、协程、协程实现TCP服务端并发、IO模型
进程池与线程池.协程.协程实现TCP服务端并发.IO模型 一.进程池与线程池 1.线程池 ''' 开进程开线程都需要消耗资源,只不过两者比较的情况下线程消耗的资源比较少 在计算机能够承受范围内最大限度 ...
- concurrent.futures进线程池和协程
concurrent.futures 异步执行进程线程池的模块,一个抽象类,定义submit,map,shutdown方法 from concurrent.futures import Process ...
- Python 37 进程池与线程池 、 协程
一:进程池与线程池 提交任务的两种方式: 1.同步调用:提交完一个任务之后,就在原地等待,等任务完完整整地运行完毕拿到结果后,再执行下一行代码,会导致任务是串行执行 2.异步调用:提交完一个任务之后, ...
- python day 20: 线程池与协程,多进程TCP服务器
目录 python day 20: 线程池与协程 2. 线程 3. 进程 4. 协程:gevent模块,又叫微线程 5. 扩展 6. 自定义线程池 7. 实现多进程TCP服务器 8. 实现多线程TCP ...
- 并发编程 --进、线程池、协程、IO模型
内容目录: 1.socket服务端实现并发 2.进程池,线程池 3.协程 4.IO模型 1.socket服务端实现并发 # 客户端: import socket client = socket.soc ...
随机推荐
- 数独 JAVA实现
数独游戏的规则从很久之前就知道,但是一直都没怎么玩过,然后到了大学,大一下学期自己学dfs的时候,刚刚好碰到了一个数独的题目,做出来后,感觉还是挺有成就感的 然后大二学了JAVA,看了下那个一些有关于 ...
- 终于遇到app不兼容,你遇到了么?
题记: 如果支付宝和QQ不兼容,要二选一,你会怎么选择? 首先了解一下背景: 笔者最近发现,微众银行的app升级到1.7.4, 而患有轻度强迫症的人是迫不及待的点了升级. 第一次,居然安装包安装不成功 ...
- SpringMVC
使用注解去完成整个项目 安装spring的一个插件,则相关的提示就会出来
- 第3章 拍摄UFO——单一职责原则
就一个类而言,应该仅有一个引起它变化的原因
- QT插件使用
1基本插件制作流程 1) 定义接口.接口定义为抽象基类,如IPluginInterface,实现高度封装.定义的头文件在最后需要通过Q_DECLARE_INTERFACE来唯一标识该接口,即通过一个全 ...
- 何为SSH协议?
该文来自百度百科,自我收藏. SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定:SSH 为建立在应用层基础上的安全协议.SSH ...
- H5(二)
音视频处理 视频处理 基本内容 使用Flash技术处理HTML页面中的视频内容 包含音频.动画.网页游戏等 特点 浏览器原生不支持(IE浏览器要求安装A ...
- python访问MS SqlServer(通过pyodbc)
#!/usr/bin/env python # -*- coding: utf-8 -*- import pyodbc class MSSQL: """ 封装pyodbc ...
- ppmoney
build/config.js 改 8080端口 build/webpack.dev.conf.js 改路径简写 alias:{ 'vux-components':'vux/dist/componen ...
- ABP集合贴(转)
ABP集合贴 本文背景 公司最近规划的新框架准备基于ABP来搭建,自从在阳铭博客看到ABP框架的介绍后,就一直持续关注着,但还没真正在实际项目中直接使用ABP,只是自己做了一些学习和Demo.ABP所 ...