在伟大的”计算机哲学“操作系统这本书中,一般给出线程的概念为:是在进程内部运行的一个执行分支(执行流),属于进程的一部分,粒度要比进程更加细腻和轻量化。大家对这一概念一看而过既可以,不必特别纠结!下面我将带大家深入理解线程的概念!
我们一般学过Windows开发的都知道,在Windows中存在单独的线程TCB。但是,Linux中没有专门为线程设计TCB,而是用进程的PCB来模拟线程。
Linux之所以采用这样的设计:不用维护复杂的进程和线程的关系,不用单独为线程设计任何算法,直接使用线程的一套相关方法。OS只需要聚焦在线程间的资源分配上就可以了!
话不多说,先来上一张图片,加入大家对Linux系统中轻量级进程的理解,如下所示:
之前的进程,内部只有一个执行流的进程。今天的进程,内部可以具有多个执行流。
创建进程的”成本“非常高,要使用的资源非常多(由1到1)成本:时间+空间。现在有了轻量级进程后,从内核视角来看:进程是承担分配系统资源的基本实体。线程是CPU调度的基本单位,承担进程资源的一部分的基本实体。进程划分资源给线程!
Linux PCB 小于等于传统意义上的进程PCB。Linux进程即为轻量级进程。在Linux中线程由OS创建,CPU调度。
Linux因为是用进程模拟的,所以Linux下不会给我们提供直接操作线程的接口,而是给我们提供,在同一个地址空间内部创建PCB的方法,分配资源给指定PCB的接口。Linux本身不会提供线程操作的接口,这对用户来说操作不是特别友好,所以系统级别的工程师,开发了一套可以让用户直接使用的接口,原生线程库(用户层)
线程在进程的地址空间内运行!CPU调度的时候只看PCB,每一个PCB曾经被指派过指向方法和数据,CPU可以直接的调度,线程属于进程的一部分。从以下几点理解之句话:
进程的多个线程共享同一地址空间,因此Text Segment、Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个全局变量,在各线程中都可以访问到,除此之外,各线程还共享以下进程资源和环境:
1)文件描述符表
2)每种信号的处理方式(SIG_IGN,SIG_DFL或者自定义的信号处理函数)
3)当前工作目录
4)用户id和组id