跳过正文

GPM<1>-进程-线程-协程

·21 字·1 分钟
Chuck Chan
作者
Chuck Chan
分享技术、思考与生活

GPM<1> 进程/线程/协程
#

进程/线程/协程
#

进程
#

进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。每一个进程都有自己独立的地址空间。

线程
#

线程是进程的一个实体,是CPU调度和分派的基本单位,线程自己基本上不拥有系统资源,但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程的上下文切换比进程的上下文切换快得多,所以对他的调度的开销会小很多,从而提高系统资源的利用率和吞吐量。

进程/线程联系与区别
#

其实Linux下并没有线程,只是为了迎合开发口味,搞了个轻量级进程出来就叫做了线程。轻量级进程和进程一样,都有自己独立的task_struct进程描述符,也都有自己独立的pid。从操作系统视角看,调度上和进程没有什么区别,都是在等待队列的双向链表里选择一个task_struct切到运行态而已。只不过轻量级进程和普通进程的区别是可以共享同一内存地址空间、代码段、全局变量、同一打开文件集合而已。线程切换和进程切换之间的主要区别在于,在线程切换期间,虚拟内存空间保持不变,而在进程切换期间则不然。那么CPU从一个task_struct切换到另一个task_struct时,是如何断定它进程间切换还是线程间切换呢?我我们可以通过task_struct里的tgid (thread group id)这个字段来判断。tgid这个字段在task_struct里代表线程的组id,即同一组(同一进程下)的线程拥有相同的tgid,当CPU切换task_struct时发现两个task_struct的tgid不同,则认为是进程切换,需要重新加载虚拟内存空间

协程
#

由上可知,线程的切换需要花费一定的CPU资源,并且随着这个线程数增多,这个资源也会一直增加。特别是在一些支撑高并发的计算机中,这个资源愈发显眼。那有什么办法可以减少这个切换的资源消耗吗?修改操作系统的内核显然不合理,那能否把这个线程移到用户态来,让用户态来执行切换?这种在用户态产生的“线程”,就叫协程,所以协程也叫用户态线程

协程的调度器在用户态,需要语言自己实现,golang正是利用GPM模型来实现对协程的支持的。