文档章节

Golang并发解读

Kanonpy
 Kanonpy
发布于 03/29 19:24
字数 1743
阅读 2
收藏 0

进程与线程

概念

在面向进程设计的系统中,进程(process)是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。 进程是程序(指令和数据)的真正运行实例。用户下达运行程序的命令后,就会产生进程。同一程序可产生多个进程(一对多关系),以允许同时有多位用户运行同一程序,却不会相冲突。

线程(thread)是操作系统能够进行运算调度的最小单位,线程分为内核线程、轻量级进程、用户线程;内核线程是指操作系统内核调度的线程,如Win32线程;用户线程是由用户进程自行调度的线程,如Linux平台的POSIX Thread; 轻量级进程(LWP)是建立在内核之上并由内核支持的用户线程。

【内核线程】<->【轻量级进程】<->【用户线程】

在用户空间模拟操作系统对进程的调度,来调用一个进程中的线程,每个进程中都会有一个运行时系统,用来调度线程。此时当该进程获取cpu时,进程内再调度出一个线程去执行,同一时刻只有一个线程执行。

内核级线程:切换由内核控制,当线程进行切换的时候,由用户态转化为内核态。切换完毕要从内核态返回用户态。

系统调度

线程本质可以看成是一系列的指令集。

线程一般分为三种状态:

  • 阻塞态:表示线程已经停止,需要等待一些事情发生后才可继续。这有很多种原因,比如需要等待硬件(磁盘或网络),系统调用,或者互斥锁(atomic, mutexes)。这类情况导致的延迟,往往是性能不佳的根本原因。
  • 就绪态:这代表线程想要一个 CPU 核来执行被分配的机器指令。如果你有很多个线程需要 CPU,那么线程就不得不等待更长时间。此时,因为许多的线程都在争用 CPU,每个线程得到的运行时间也就缩短了。
  • 运行态:这表示线程已经被分配了一个 CPU 核,正在执行它的指令。与应用相关的工作正在被完成。这是每个人都想要的状态。

CPU密集型任务和IO密集型任务 CPU密集处理任务中线程很少进入阻塞态。它一直都需要使用 CPU,因此线程的切换并没有用,甚至会产生负面效果,主要通过多核并行来解决问题。这种工作通常都是数学计算。比如计算圆周率的第 n 位的工作就属于 CPU密集型的工作。 IO密集任务线程会经常进入阻塞态,比如网络请求资源,或者系统调用。一个需要访问数据库的线程属于 IO密集的。互斥锁的使用也属于这种。这时候线程的切换来提升并发量。

线程调度存在的问题

昂贵的代价

  • 上下文切换
  • Cache Line 命中率

上下文切换

上下文切换是指调度器把一个线程从CPU核上拿下来,把另一个就绪态的线程放到CPU核上。线程的上下文切换时间一般是50~100ns,这是为什么如果对于计算密集型的任务频繁切换反而会导致效果更差。

Cache Line 命中率

由于访问主内存很耗时间,CPU大部分会访问cache,现代CPU缓存一般分为了三层。离CPU越远的,其访问速度越慢。因此提高 Cache Line 命中率是提高性能的很重要的而一种方法,一般来说优化缓存可从三个方面入手:一、减少命中时间;二、降低失效率;三、减轻失效代价。 但是,对于多核系统来说,多线程在每个核都有一份它自己所需要数据的拷贝,随着 CPU 核上运行的线程的改变,不同的线程需要访问的数据不同,从而导致同一个 cache line 中的数据被修改了,其他所有核上的 cache line 拷贝都标记为“不可用”,当其他核上的线程试图访问或修改这个数据时,需要重新从主内存上拷贝最新的数据到自己的 cache 中。

Goroutine 的模型设计

P:是一个逻辑处理器的概念,当P有任务时需要创建或者唤醒一个系统线程来执行它队列里的任务,所以P/M绑定构成一个执行单元。 当你的 Go 程序启动之初,它会被分配一个逻辑处理器,每一个 P 会被分配一个系统线程(M)。这个 M 会被操作系统调度,操作系统把线程(M)放到一个 CPU Core 上去执行,在执行的时候,每个线程都被绑定上了一个独立的 P 。

M:是一个线程或称为Machine,所有M是有线程栈的。

G:表示一个Goroutine。

执行队列 在 Go 调度器中有 2 个不同的执行队列:全局队列(Global Run Queue, 简称 GRQ)和本地队列(Local Run Queue,简称 LRQ)。每一个 P 都会有一个 LRQ 来管理分配给 P 上的 Goroutine。这些 Goroutine 轮流被交付给 M 执行。GRQ 是用来保存还没有被分配到 P 的 Goroutine。 LRQ是 Lock-Free 的,处理速度快;GRQ为保证数据竞争问题,需要加锁处理,速度比LRQ慢,因此 P 处理完LRQ的时候会先找其他 P 的LRQ,最后再去找GRQ。

goroutine队列调度

runtime.schedule() {
    // only 1/61 of the time, check the global runnable queue for a G.
    // if not found, check the local queue.
    // if not found,
    //     try to steal from other Ps.
    //     if not, check the global runnable queue.
    //     if not found, poll network.
}

Goroutine调度为何更好?

  • Go的调度是基于用户态事件而非抢占式的,比如关键字go、垃圾回收、同步互斥操作如Lock() Unlock()
  • Go通过尽可能多在M上来运行goroutine,从而提高CPU的利用率,Go通过"spinning threads"最小化系统线程的切换。
  • 利用gorountine可以避免系统线程的切换,从而提高Cache Line 命中率。
  • 线程的stack size更大(≥ 1MB),而gorountine得stack size只有2KB,启动更慢。

更多精彩:https://www.shikanon.com/

© 著作权归作者所有

Kanonpy
粉丝 16
博文 42
码字总数 45373
作品 0
广州
程序员
私信 提问
Go语言入门——数组、切片和映射

Go语言入门——数组、切片和Map 按照以往开一些专题的风格,第一篇一般都是“从HelloWorld开始” 但是对于Go,思来想去,感觉真的从“HelloWorld”说起,压根撑不住一篇的篇幅,因为Go的Hel...

Jackie_Zheng
05/19
0
0
golang VS php 性能对比

原文 http://www.isno.cn/2013/12/golang-vs-php/ 在工作的项目中,我的主要开发语言是php,因需求或者为弥补php的缺陷,需要为php做各种各样的扩展,比如php本身不支持线程,没有队列,进程也...

神仙
2013/12/19
30.7K
34
Go1.6 和 Go语言圣经中文版 正式发布!

Go1.6 和 Go语言圣经中文版 正式发布! Go1.6正式版本发布。在 https://golang.org/doc/go1.6 可以预览Go1.6的发布信息。自Go1.5发布以来的重大变化有以下几个: 《Go语言圣经》 面世标志着G...

chai2010
2016/01/27
10.4K
18
基于 PHP 协程的网络服务框架--Zan PHP Framework

Zan PHP Framework 是有赞开源的基于 PHP 协程的网络服务框架,提供最简单的方式开发面向 C10K+ 的高并发SOA服务和RPC服务。 该项目每天为2,000+个服务提供300,000,000+次访问量支持,广泛应...

匿名
2017/06/21
2.4K
6
在windows下配置Eclipse + go环境 Eclipse平台下配置Go语言开发环境(Win

mongoDB: mongoDB数据库基本操作 Programming in Go (Golang) – Setting up a Mac OS X Development Environment 造完美的go开发环境 在windows下配置Eclipse + go环境 Eclipse平台下配置G......

d_watson
2016/06/03
27
0

没有更多内容

加载失败,请刷新页面

加载更多

计算机实现原理专题--二进制减法器(二)

在计算机实现原理专题--二进制减法器(一)中说明了基本原理,现准备说明如何来实现。 首先第一步255-b运算相当于对b进行按位取反,因此可将8个非门组成如下图的形式: 由于每次做减法时,我...

FAT_mt
今天
5
0
好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
今天
7
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
今天
6
0
【技术分享】TestFlight测试的流程文档

上架基本需求资料 1、苹果开发者账号(如还没账号先申请-苹果开发者账号申请教程) 2、开发好的APP 通过本篇教程,可以学习到ios证书申请和打包ipa上传到appstoreconnect.apple.com进行TestF...

qtb999
今天
10
0
再见 Spring Boot 1.X,Spring Boot 2.X 走向舞台中心

2019年8月6日,Spring 官方在其博客宣布,Spring Boot 1.x 停止维护,Spring Boot 1.x 生命周期正式结束。 其实早在2018年7月30号,Spring 官方就已经在博客进行过预告,Spring Boot 1.X 将维...

Java技术剑
今天
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部