这几天深入的研究了一下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池控制协程的大小的更多相关文章

  1. 死磕 java线程系列之自己动手写一个线程池

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. (手机横屏看源码更方便) 问题 (1)自己动手写一个线程池需要考虑哪些因素? (2)自己动手写 ...

  2. 手写一个线程池,带你学习ThreadPoolExecutor线程池实现原理

    摘要:从手写线程池开始,逐步的分析这些代码在Java的线程池中是如何实现的. 本文分享自华为云社区<手写线程池,对照学习ThreadPoolExecutor线程池实现原理!>,作者:小傅哥 ...

  3. python-进程池与线程池,协程

    一.进程池与线程池 实现并发的手段有两种,多线程和多进程.注:并发是指多个任务看起来是同时运行的.主要是切换+保存状态. 当我们需要执行的并发任务大于cpu的核数时,我们需要知道一个操作系统不能无限的 ...

  4. 并发编程(六)——进程/线程池、协程、gevent第三方库

    进程/线程池.协程.gevent第三方库 一.进程/线程池 1.进程池 (1)什么是进程池 如果需要创建的子进程数量不大,可以直接利用multiprocess中的Process来创建.但是当需要创建上 ...

  5. 进程池与线程池、协程、协程实现TCP服务端并发、IO模型

    进程池与线程池.协程.协程实现TCP服务端并发.IO模型 一.进程池与线程池 1.线程池 ''' 开进程开线程都需要消耗资源,只不过两者比较的情况下线程消耗的资源比较少 在计算机能够承受范围内最大限度 ...

  6. concurrent.futures进线程池和协程

    concurrent.futures 异步执行进程线程池的模块,一个抽象类,定义submit,map,shutdown方法 from concurrent.futures import Process ...

  7. Python 37 进程池与线程池 、 协程

    一:进程池与线程池 提交任务的两种方式: 1.同步调用:提交完一个任务之后,就在原地等待,等任务完完整整地运行完毕拿到结果后,再执行下一行代码,会导致任务是串行执行 2.异步调用:提交完一个任务之后, ...

  8. python day 20: 线程池与协程,多进程TCP服务器

    目录 python day 20: 线程池与协程 2. 线程 3. 进程 4. 协程:gevent模块,又叫微线程 5. 扩展 6. 自定义线程池 7. 实现多进程TCP服务器 8. 实现多线程TCP ...

  9. 并发编程 --进、线程池、协程、IO模型

    内容目录: 1.socket服务端实现并发 2.进程池,线程池 3.协程 4.IO模型 1.socket服务端实现并发 # 客户端: import socket client = socket.soc ...

随机推荐

  1. Python中操作mysql的pymysql模块详解

    Python中操作mysql的pymysql模块详解 前言 pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前pymysql支持python3.x而后者不支持 ...

  2. 使用httpclient 调用selenium webdriver

    结合上次研究的selenium webdriver potocol ,自己写http request调用remote driver代替selenium API selenium web driver ...

  3. Linux下GNOME桌面的安装

    yum grouplist //列出yum仓库里的软件组列表 GNOME桌面的安装 yum install soft1 soft2 //使用yum源安装软件 yum groupinstall grou ...

  4. 关于C3翘边阴影的demo

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  5. Python初学者应了解的技巧

    交换变量 x = 6 y = 5 x, y = y, x print x >>> 5 print y >>> 6 if 语句在行内 print "Hell ...

  6. Reason: image not found

    刚生的Xcode8,出现好多Error,有些Error真的太麻烦不想记录,现在这个挺简单的,就记下来,控制台输出的Error信息如下: fix: Target -> Build Phases - ...

  7. Lintcode 150.买卖股票的最佳时机 II

    ------------------------------------------------------------ 卧槽竟然连题意都没看懂,百度了才明白题目在说啥....我好方啊....o(╯□ ...

  8. GTest Google的一种白盒单元测试框架 开源项目

    GTest为google开源的白盒单元测试跨平台测试框架,含丰富的断言.类型参数化测试.死亡测试.以及其他的测试选项设置.文件保存等,以下将对该项目C++的实现进行简要的分析,作为学习记录备份. 基本 ...

  9. Officel常用操作

    Excel: 1.隔行变色|菜单->条件格式->其它规则->使用公式->"=MOD(ROW(),2)=0" 2.查找包含特定字符的单元格,并替换整个单元格 ...

  10. [Idea] 在idea中使用jetty debug

    1.添加jetty的maven插件 <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId> ...