进程、线程、协程的区别

1. 进程

通俗的讲,应用程序运行起来就是进程,一个应用程序一般对应一个进程(也可多个);

每个进程都有自己的独立内存空间,拥有自己独立的地址空间、独立的堆和栈,既不共享堆,亦不共享栈;

进程由操作系统调度 ,操作系统会以进程为单位,分配系统资源(CPU时间片、内存等资源),进程是资源分配的最小单位。

2. 线程

一个进程一般有一个主线程,还有若干个辅助线程,线程之间是平行运行的;

线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是这样的),是操作系统调度(CPU调度)执行的最小单位。

3. 协程 

在线程里面可以开启协程,一个线程也可以拥有多个协程,协程的调度完全由程序员在代码里控制。协程和线程一样共享堆,不共享栈,协程就像轻量级的线程,在切换开销方面,协程远比线程小。

协程与线程主要区别是它将不再被操作系统内核调度,而是交给了程序自己,这样带来的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源,而线程是将自己交给内核调度。

4. goroutine

协程和golang中的协程(goruntine)是不一样的,Go 协程通过通道来通信而协程通过让出和恢复操作来通信;而且Go 协程比协程更强大。因为Golang 在 runtime、系统调用等多方面对 goroutine 调度进行了封装和处理,也就是Golang 有自己的调度器,工作方式基本上是协作式,而不是抢占式,但也不是完全的协作式调度,例如在系统调用的函数入口处会有抢占。当遇到长时间执行或者进行系统调用时,会主动把当前 goroutine 的CPU (P) 转让出去,让其他 goroutine 能被调度并执行,也就是我们为什么说 Golang 从语言层面支持了协程。简单的说就是golang自己实现了协程并叫做goruntine

goroutine(运行时)会在逻辑处理器上调度这些goroutine来运行,一个逻辑处理器绑定一个操作系统线程(指的是操作系统线程,即内核线程)。

当我们创建一个goroutine的后,会先存放在全局运行队列中,等待Go运行时的调度器进行调度,把他们分配给其中的一个逻辑处理器,并放到这个逻辑处理器对应的本地运行队列中,最终等着被逻辑处理器执行即可。

  golang中设置逻辑处理器个数也非常简单,在程序开头使用runtime.GOMAXPROCS(逻辑CPU数量)即可,一般情况下,可以使用 runtime.NumCPU() 查询 CPU 数量,并使用runtime.GOMAXPROCS() 函数进行设置,当参数小于 1 时使用默认值。

对于逻辑处理器的个数,不是越多越好,要根据电脑的实际物理核数,Go 1.5 版本之前,默认使用的是单核心执行。从 Go 1.5 版本开始,默认执runtime.GOMAXPROCS(runtime.NumCPU()),最大效率地利用 CPU。

runtime.NumCPU()默认物理CPU数,

 

go语言中并发指的是让某个函数独立于其他函数运行的能力。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开心码农1号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值