Golang CSP并发机制及使用模型
作者:falm 发布时间:2023-09-15 16:13:27
今天介绍一下 go语言的并发机制以及它所使用的CSP并发模型
CSP并发模型
CSP模型是上个世纪七十年代提出的,用于描述两个独立的并发实体通过共享的通讯 channel(管道)进行通信的并发模型。 CSP中channel是第一类对象,它不关注发送消息的实体,而关注与发送消息时使用的channel。
Golang CSP
Golang 就是借用CSP模型的一些概念为之实现并发进行理论支持,其实从实际上出发,go语言并没有,完全实现了CSP模型的所有理论,仅仅是借用了 process和channel这两个概念。process是在go语言上的表现就是 goroutine 是实际并发执行的实体,每个实体之间是通过channel通讯来实现数据共享。
Channel
Golang中使用 CSP中 channel 这个概念。channel 是被单独创建并且可以在进程之间传递,它的通信模式类似于 boss-worker 模式的,一个实体通过将消息发送到channel 中,然后又监听这个 channel 的实体处理,两个实体之间是匿名的,这个就实现实体中间的解耦,其中 channel 是同步的一个消息被发送到 channel 中,最终是一定要被另外的实体消费掉的,在实现原理上其实是一个阻塞的消息队列。
Goroutine
Goroutine 是实际并发执行的实体,它底层是使用协程(coroutine)实现并发,coroutine是一种运行在用户态的用户线程,类似于 greenthread,go底层选择使用coroutine的出发点是因为,它具有以下特点:
用户空间 避免了内核态和用户态的切换导致的成本
可以由语言和框架层进行调度
更小的栈空间允许创建大量的实例
可以看到第二条 用户空间线程的调度不是由操作系统来完成的,像在java 1.3中使用的greenthread的是由JVM统一调度的(后java已经改为内核线程),还有在ruby中的fiber(半协程) 是需要在重新中自己进行调度的,而goroutine是在golang层面提供了调度器,并且对网络IO库进行了封装,屏蔽了复杂的细节,对外提供统一的语法关键字支持,简化了并发程序编写的成本。
Goroutine 调度器
上节已经说了,golang使用goroutine做为最小的执行单位,但是这个执行单位还是在用户空间,实际上最后被处理器执行的还是内核中的线程,用户线程和内核线程的调度方法有:
N:1 多个用户线程对应一个内核线程
1:1 一个用户线程对应一个内核线程
M:N 用户线程和内核线程是多对多的对应关系
golang 通过为goroutine提供语言层面的调度器,来实现了高效率的M:N线程对应关系
调度示意
图中
M:是内核线程
P : 是调度协调,用于协调M和G的执行,内核线程只有拿到了 P才能对goroutine继续调度执行,一般都是通过限定P的个数来控制golang的并发度
G : 是待执行的goroutine,包含这个goroutine的栈空间
Gn : 灰色背景的Gn 是已经挂起的goroutine,它们被添加到了执行队列中,然后需要等待网络IO的goroutine,当P通过 epoll查询到特定的fd的时候,会重新调度起对应的,正在挂起的goroutine。
Golang为了调度的公平性,在调度器加入了steal working 算法 ,在一个P自己的执行队列,处理完之后,它会先到全局的执行队列中偷G进行处理,如果没有的话,再会到其他P的执行队列中抢G来进行处理。
来源:https://www.jianshu.com/p/36e246c6153d
猜你喜欢
- 很多朋友和我讨论了一些关于网站开发到底使用哪种语言最合适,尤其是到网站一定有一定流量的时候,到底那种web语言更适合做站呢,精灵这里根据自己
- 如下图,我们在做图片logo列表的时候通常是用li标签来实现。html:<ul class="logolist&q
- 解决Microsoft VBScript 运行时错误 (0x800A0046) 没有权限的解决方案,0x800a0046错误。前段时间在做站
- 设置密码保护SqlServer数据库备份文件! 备份SqlServer数据库 Backup Database [数据库] To disk=&
- 文通过一个操作实例来说明SQL中主标识列IDENTITY的使用技巧。要求:在 sql server 2005中,建立数据表book,在表bo
- 如下所示:interval=stats.t.interval(a,b,mean,std)t分布的置信区 间a:置信水平b:检验量的自由度me
- 随着网络的发展,人们通过各种方式使用它。今天,网络购物,跟朋友或者不认识的人聊天,管理银行账户,以及一些日常应用,共享照片或视频,等等。事实
- 代码演示如下:方法一<?php function encryptDecrypt($key, $string, $decrypt){
- 有的时候取出全部数据库记录也许正好满足你的要求,不过,在大多数情况下我们通常只需得到部分记录。这样一来该如何设计查询呢?当然会更费点脑筋了,
- 今天一个同事报告一个问题,表都不能使用了,检查了一下,发现问题 db2 => select * from testACTNO ACTK
- 1、说明*,nkw表示命名关键字参数,是用户想输入的关键字参数名称,定义方式是在nkw前追加*,2、作用限制调用者传达的参数名称。3、实例#
- 需求背景公司前端使用 Highcharts 构建图表,图表的图例支持点击显示或隐藏相应的指标。现在有需求后端需要存储用户在前端点击后显示图表
- 因为主键可以唯一标识某一行记录,所以可以确保执行数据更新、删除的时候不会出现张冠李戴的错误。当然,其它字段可以辅助我们在执行这些操作时消除共
- Array.prototype._ = function(){var _p = 0;var _v = 0;(function(){ 
- 定义列表和其他类型的列表稍有不同,它由两部分组成:名称和定义。DT 指定名称,为内联元素。DD 指定定义,为块级元素。标准属性id, cla
- 一、逻辑数据库和表的设计数据库的逻辑设计、包括表与表之间的关系是优化关系型数据库性能的核心。一个好的逻辑数据库设计可以为优化数据库和应用程序
- 本文实例分析了php字符串截取函数用法。分享给大家供大家参考。具体分析如下:php自带的截取字符串的函数只能处理英文,数字的不能截取中文混排
- 如果仅仅是定义表格的边框为1(border="1")和边框颜色值(如borderC
- QQ影音至9月发布之后一直口碑很好,视觉界面和交互设计也颇受好评,这是设计师们努力的结果,也是众多用户反馈的功劳。我们希望可以提供更多价值回
- 2008年,对于JavaScript来说是非常振奋人心的一年,很多高人加入到JavaScript和Web开发的阵营中来,浏览器厂商在技术上互