当前位置:网站首页>Go简单实现协程池
Go简单实现协程池
2022-08-02 02:52:00 【免费的东西】
首先就是进程、线程、协程讲解老三样。
**进程:**本质上是一个独立执行的程序,进程是操作系统进行资源分配和调度的基本概念,操作系统进行资源分配和调度的一个独立单位。
**线程:**是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个进程中可以并发多个线程,每条线程执行不同的任务,切换受系统控制。
**协程:**又称为微线程,是一种用户态的轻量级线程,协程不像线程和进程需要进行系统内核上的上下文切换,协程的上下文切换是由用户自己决定的,有自己的上下文,所以说是轻量级的线程,也称之为用户级别的线程就叫协程,一个线程可以多个协程,线程进程都是同步机制,而协程则是异步Java的原生语法中并没有实现协程,目前python、Lua和GO等语言支持。
**关系:**一个进程可以有多个线程,它允许计算机同时运行两个或多个程序。线程是进程的最小执行单位,CPU
的调度切换的是进程和线程,进程和线程多了之后调度会消耗大量的CPU,CPU上真正运行的是线程,线程可
以对应多个协程。
golang协程
MPG模型
Go协程中有三个关键实体:
- M(machine): 工作线程,由操作系统调度。应该就是通常所说的内核线程。
- P(processor): 处理器(非CPU),代表着运行Go代码的必要资源,以及调度goroutine的能力。个人觉得可以当作拥有自主调度权的算法模块,用于工作窃取(work stealing)。
- G(gooutine): Go协程,轻量级用户线程。主要包含执行栈和调度管理器。这里的调度管理器指的是,统一并管理调度资源,等待被调度。
Go协程的特点
(1)有独立的栈空间
(2)共享程序的堆空间
(3)协程调度由用户控制(进程的控制是有操作系统控制,程序员不能控制)
(4)协程是轻量级的线程
通道的特性
Go语言中的通道(channel)是一种特殊的类型。在任何时候,同时只能有一个 goroutine 访问通道进行发送和获取数据。goroutine 间通过通道就可以通信。
通道像一个传送带或者队列,总是遵循先入先出(First In First Out)的规则,保证收发数据的顺序。
当然协程的轻量性并不代表可以随意滥用,毕竟还是存在资源的消耗。本文主要讲解go的协程池的实现原理,利用select来监听任务。【代码仅用作实现原理,想更优雅可以在该原理基础上自行优化】
废话不多说直接上代码!
package main
import (
"strconv"
"time"
)
/**
协程池
*/
//全局任务管道地址数组
var arr []*chan func()
//启动任务数量
var num = 10
//默认管道下标0
var index = 0
//任务开关
var static = false
func run(f *chan func()){
println("等待咯")
for static == true {
select {
case fu:=<-*f : // 检测有没有数据可读
// 一旦成功读取到数据,则进行该case处理语句
fu()
default:
//println(f)
//println("无数据")
}
time.Sleep(time.Duration(1)*time.Second)
}
}
//启动任务函数
func Start(){
static = true
for i:=0;i<num;i++ {
//make一个管道地址
c:=make(chan func(),1)
println(&c)
//将该地址存入全局数组中
arr = append(arr,&c)
//地址传入任务函数
go run(&c)
}
}
//插入任务
func add(str string) {
//此处不是很优雅,自行优化实现。
if(index >= num-1){
index = 0
}else{
index++
}
//向地址管道传入函数
*arr[index] <- func() {
println(str)
}
}
//停止任务
func stop() {
//终止任务for
static = false
//清空管道数组
arr = []*chan func(){}
}
func main() {
Start()
println("开始执行写入管道")
println(len(arr))
for i:=0;i<1000000000;i++ {
add("传入的i:"+strconv.Itoa(i))
}
time.Sleep(time.Duration(2)*time.Second)
stop()
//time.Sleep(time.Duration(100)*time.Second)
}
原理很简单,就是合理使用select来监听管道是否有数据,协程池的实现就是合理利用管道。可以根据该思路来进行优化封装一个属于自己的协程池哦~
对于优化建议,有牛可评论,相互学习!
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦
边栏推荐
- 罗德里格斯公式(Rodrigues‘ Rotation Formula)推导
- MySQL索引优化实战
- 咨询cdc for oracle,增量同步scan.startup.mode只有initial和la
- 国标GB28181协议EasyGBS平台兼容老版本收流端口的功能实现
- mysql8.0.28 download and installation detailed tutorial, suitable for win11
- Redis主从、哨兵、 Cluster集群一锅端!
- 灰度传感器、、、diy原理。。图
- Flask 报错:WARNING This is a development server. Do not use it in a production deployment
- 生成器知道鉴别器在无条件GANs中应该学习什么
- AcWing 1285. 单词 题解(AC自动机)
猜你喜欢
随机推荐
数仓:为什么说 ETL 的未来不是 ELT,而是 EL (T)
MySQL8.0.28安装教程
ros多客户端请求服务
Chapter 11_Database Design Specifications
Chrome浏览器无法加载已解压的.crx文件的解决办法
【无标题】【Koltin Flow(三)】Flow操作符之中间操作符(二)
【LeetCode】145.二叉树的后序遍历
790. 数的三次方根
- daily a LeetCode 】 【 9. Palindrome
Recursively check if a configuration item has changed and replace it
7、MySQL Workbench 导出导入数据库
analog IC layout-Design for reliability
有人知道HTML怎么到MYSQL数据库吗? (NODEJS)
Nacos源码分析专题(一)-环境准备
analog IC layout-Parasitic effects
(1) Redis: Key-Value based storage system
四元数、罗德里格斯公式、欧拉角、旋转矩阵推导和资料
MySQL六脉神剑,SQL通关大总结
Qt自定义控件和模板分享
第11章_数据库的设计规范