操作系统与进程/线程

April 11, 2017 by Sylvenas

线程与进程可以说是老生常谈的话题了

只要是懂事计算机相关的小伙伴,提起这个大都思如泉涌,多线程,多进程,高并发等等各种零碎的概念和认知或许难以汇成一个成体系的知识结构,我们先来罗列一下这两个概念简介的官方解释。

  • 进程(process): 处于执行期的代码,正在运行的程序,它不仅包括代码,还有数据、资源、状态和虚拟的计算机
  • 线程(thread): 一个程序里的一个执行路线就叫做线程。更准确的定义是:线程是一个进程内部的控制程序

上面的概念依然让人一头雾水,还是看图说明吧

process-thread

感受进程

进程其实遍布在我们电脑的每个角落,刚刚被对面团灭的英雄联盟,云音乐正在播放的歌曲等等,都是一个个运行中的进程。

进程其实是处于执行期的程序和相关资源的总称,里面包含了要执行的代码段,需要用到的文件,端口,硬件资源,很常见的一种说法是进程是资源分配的最小单位,这句话更直白的说就是,要运行某个可执行的代码段会需要某些资源,当这个代码段运行起来的时候,这些资源也必须被分配给他。

那我们总结下就是: 运行中的代码+他占有的资源 = 进程

感受线程

讲完进程后,有些小伙伴可能懵了。

进程= 运行的代码段 + 资源,那我们的线程存在的意义在哪?为什么不直接让进程去运行。

上面我们提到了,进程是资源分配的最小单位,意味着进程和资源是 1:1 ,与之对应的一句话就是,线程是调度的最小单位,进程和线程是一个 1:n 的关系。

举个不完全恰当的栗子:我们把一家商场比做一台计算机,里面一个一个的店家就是进程,他们是商场资源的最小单位了,他们既有对应的资源,也在进行着商业活动,就如同一个有资源和在运行中的进程。

每个商铺里面的店员就是一个个线程,他们在自己的资源里各司其职,有人拉客,有人站台,有人把风。这些人才是真正调度的最小单位。

我们试想,如果资源的分配和调度是 1:1 的关系,那意味着一个商店里在活动的人同一时间只能有一个,当你在拉客的时候,其他人不可以在店里,你在站台的时候,其他人也只能在一边候着,但其实你们都是用的同一家店铺的资源。

这显然不 OK,所以进程同理,在 进程中使用多线程就是让共享同一批资源的操作一起进行 。

这样可以极大的减少进程资源切换的开销。当我们在进行多个操作的时候,他们相互之间在切换时自然是越轻量越好。

就像玩手机的时候,你在刷微博,这时你忽然又想玩游戏,当你在这两个操作之间切换的时候,自然是 越轻越好 ,你无需把手关机再重启,然后再打开游戏吧,不然这手机也太弱鸡了吧~~

进程与线程切换的代价

既然说到了进程的切换,那我们可以细探一下进程切换的开销。一个进程会独占一批资源,比如使用寄存器,内存,文件等。

当切换的时候,首先会保存现场,将一系列执行的中间结果保存起来,存放在内存中的程序的代码和数据,它的栈、通用目的寄存器的内容、程序计数器、环境变量以及打开的文件描述符的集合,这个状态叫做上下文

然后在他恢复回来的时候又需要将上述资源切换回去。显而易见,切换的时候需要保存的资源越少,系统性能就会越好,线程存在的意义就在于此。线程有自己的上下文,包括唯一的整数线程 ID,栈、栈指针、程序计数器、通用目的寄存器和条件码。

可以理解为线程上下文是进程上下文的子集

线程之下,协程

程序的编写总是追求最极致的性能优化,线程的出现让共享同一批资源的程序在切换时更轻量,那有没有比线程还要轻的呢?

协程的出现让这个变成了可能,线程和进程是操作系统的支持带来的优化,而协程本质上是一种应用层面的优化了。

这就如同线程和进程是天生的游戏奇才,超神玩家,协程是这位奇才觉得自己超神不够还想超鬼,是自己又做了后天努力。

协程可以理解为特殊的函数,这个函数可以在某个地方挂起,并且可以重新在挂起处外继续运行,简单来说, 一个线程内可以由多个这样的特殊函数在运行 ,但是有一点必须明确的是,一个线程的多个协程的运行是串行的。

Note: 如果是多核 CPU,多个进程或一个进程内的多个线程是可以并行运行的,但是一个线程内协程却绝对是串行的,无论 CPU 有多少个核。

毕竟协程虽然是一个特殊的函数,但仍然是一个函数。一个线程内可以运行多个函数,但这些函数都是串行运行的。当一个协程运行时,其它协程必须挂起。

Linux 之线程进程

Linux 的设计总让人有种化繁为简的感觉,除了大家熟悉的一切皆文件,他对进程线程的设计也是类似的感觉,严格来说在 Linux 上并没有线程的概念,此话怎么说?

因为无论是进程还是线程,都要有 存在的证明 ,你说你在世界上存在,你怎么证明呢?

进程的存在证明就是进程控制块,Linux 每一个进程都有其对应的控制块,里面包含了进程 id,需要的硬件资源,执行的代码段等等。线程亦如是,在 windows 中有明确的线程控制块,由操作系统来做线程调度。

Linux 视线程和进程是一样的,都用进程控制块进行管控,但这并不等于 Linux 不支持线程,只是不同操作系统对概念的抽象不同,Linux 提供 pthread 库来 fork 微进程,多个微进程可以共享资源,和线程本质上并无区别,只是没有提供专门的线程管控,有兴趣的同学可以详细了解下。

并行

多 CPU,影分身~ 要成为 nb 的 业界大手 ,你要会哪些技能?

面试扛千亿并发,入职调按钮样式,哈哈哈。

这里有个概念是并发,与之烂兄烂弟的概念就是并行,让人意乱神迷傻傻分不清。

现在我们经常会听到各种名词,什么多核机器,多 cpu 什么的。多个 cpu 意味着什么呢?

首先要搞清楚 cpu 到底是干嘛的。cpu 的作用用两个字来讲就是: 计算 。

我们的各种花里胡哨的代码,最终 编译完 真正执行的时候也无非这两个字:计算。上面提到了进程一定是在运行的代码,那代码的运行必然就是在 CPU 上。

我们有几个 cpu 意味着我们可以有几个程序同时在计算,这就是 并行 ,就如同小时候会想有鸣人的影分身,就可以让他们一个来写数学,一个来写语文,一个来写英语。

与多核对应的就是苦逼的单核今计算机了,就像没有影分身的我,这个时候也有多个作业要做,咋整?半个小时写语文,半个小时写数学,再半个小时写语文,再来半小时写数学。。(强行时间片轮转了)这是语文数学英语也都同时写了,但实际上只有我苦逼的一个人,这就是分时 并发 ,但非并行。