更多优质内容
请关注公众号

操作系统入门(四)线程概念、与进程的关系和线程模型-阿沛IT博客

正文内容

操作系统入门(四)线程概念、与进程的关系和线程模型

栏目:其他内容 系列:操作系统入门 发布时间:2022-02-13 15:51 浏览量:1966
本系列文章目录
展开/收起

线程是调度和运行的最小单位(程序执行流的最小单位)。

 

为什么引入线程?

传统进程机制中,一个进程内的代码只能串行运行,但是一个进程可能也需要同时处理多个任务,例如QQ软件可能要同时运行视频聊天的处理程序,也要运行传送文件程序。

为了满足这种需求,操作系统引入了线程,进程就不再是运行调度的最小单位,而只是资源分配的单位,线程变成了运行调度的最小单位(作为CPU的分配单元),同一个进程内的线程之间可以并发,不同进程之间(的线程)也可以并发,进一步提高了计算机并发程度。

 

进程具的两个明显属性:资源分配的单位和运行调度的单位。

进程实体具有自己的内存空间,包括程序、数据、PCB和栈,还有其他资源如打开的文件、占用的设备等,这是他的资源分配属性。而它的调度和运行属性被赋予了一个新的实体——线程。系统对进程的调度运行实际上是对线程的调度运行。

 

引入了线程后发生了什么变化

 

 

线程的属性

线程是调度的单位;

每个线程都有一个线程ID和线程控制块(TCB);

线程也有就绪、阻塞和运行这3种基本状态;

线程几乎不独立拥有系统资源,而是共享进程内的资源,但线程可以独立拥有CPU资源(一个进程内的多个线程可以在不同的CPU上并行运行证明线程可以拥有CPU资源)。

由于共享进程的内存空间,因此同一个进程中的线程间通信几乎无需系统干预;

切换同一进程的线程不会引起进程切换,开销很小;切换不同进程的线程会引起进程切换,开销大。

 

问题:为什么创建进程的开销 > 创建线程的开销?为什么切换进程的开销 > 切换线程的开销?

开销可以分为时间开销和空间开销。

研究为什么创建进程的开销 > 创建线程的开销,就要先知道创建进程比创建线程时多了资源的分配。

从空间开销上,创建一个进程需要为该进程分配内存、IO设备、文件等资源,内部线程无法被系统单独分配资源,只需要共享进程的这些资源即可,所以一个线程占用的资源不可能超过它所在进程的资源,因此从空间开销上进程占用空间和资源的开销肯定大于线程;

从时间开销上,创建一个进程时需要将该进程的程序从磁盘装入内存,涉及磁盘IO请求到响应的时间(磁头定位磁道和扇区,数据在磁盘和内存间拷贝);分配资源时,如果该资源是互斥共享的且被其他进程占用,进程还需要等待资源被释放才能从创建态进入就绪态;创建进程时,也会为该进程创建一个主线程,因此创建线程的时间已经被包含在了创建进程的时间里,因此创建进程的开销创建线程的开销并不是独立的两个开销而是包含关系。实际上创建一个线程的开销无非是创建一个TCB的时间开销,其他该做的进程都已经帮线程做好了。

 

研究为什么切换进程的开销 > 切换线程的开销,就要先知道进程之间的内存空间是独立的,同一进程内的线程是共享该进程的内存空间的。

进程的切换其本质是不同进程的线程间切换,因此原问题就变成为什么切换不同进程的线程的开销 > 切换同一进程内线程的开销,前者比后者多做了什么事。

线程的切换包含2个步骤:CPU接收和处理中断(时钟中断或IO设备发出的中断);保存和恢复线程的CPU现场环境(各种寄存器的值),这是前者和后者都会做的事情。

不同进程的线程切换后会导致快表的页表项和高速缓存失效(因为快表中的页表项和高速缓存缓存的是上一个进程的数据),因此进程切换后访问内存会较慢,需要花时间重新构建自己的高速缓存和快表缓存,而同一进程的线程由于共享进程的内存因此切换后页表项和高速缓存并不会失效。

此外进程切换可能导致系统从外存换入新进程页面,换出上一个进程的页面,这也会消耗CPU时间。

 

此外,进程间通信也比同一进程间的线程通信开销大,无论是使用共享内存还是使用管道通信,都是委托操作系统将数据写入共享内存和管道(或者委托OS取出),需要进行系统调用。而线程间通信无需系统调用,因为他们本身就共享同一进程的内存空间。

 

线程组成

每个线程都有一个TCB结构(线程控制块)用于保存线程自己的私有信息,thread包含:

1、一个唯一的线程标识符

2、CPU运行现场(如程序计数器、状态寄存器、通用寄存器的值等)。

3、分别指向核心栈和用户栈的两个栈指针,当CPU转为核心态运行时使用核心栈,在用户态运行时则使用自己的用户栈。

 

每一个线程都有自己的CPU运行现场,即运行时寄存器的值,以及自己的私有栈(上一节介绍“进程组成的真相”一图中的用户栈是main主线程的栈,而子线程的栈在其他地方)。

 

 

- 线程和进程关系

一个进程可以有多个线程,但至少要有一个线程;一个线程只能在该进程的地址空间活动。

资源分配给进程,同一进程下的所有线程共享该进程所有资源。

处理机分配给线程,真正在处理机上运行的是线程。

 

 

- 线程的实现

线程的实现分为 用户级线程 和 系统级线程 两种方式。

用户级线程的管理工作(创建、调度和回收)都由用户程序控制无需操作系统干预,内核对线程一无所知(用户级线程对内核透明,内核只知道进程的存在,不知道线程的存在)。

优点:

线程切换很快,开销小,无需系统调用,无需切换到核心态;

调度算法可以自己实现;

可以运行在任何操作系统,包括不支持线程的操作系统也可以实现用户级线程。

缺点:

系统调用引起的阻塞会阻塞进程中所有线程(因为内核不知道进程内的线程存在,只知道进程的存在,进程的用户级线程阻塞会被系统当做整个进程阻塞)

同一进程中的多线程只能并发不能并行,因为他们只能运行在一个CPU上,用户程序在同一个进程时间片内切换多个线程。

 

 

 

 

内核级线程的管理工作由操作系统内核完成,因此内核级线程的切换必然需要在核心态下才 能完成。操作系统会为每个内核级线程建立相应的 TCB。优点是并发度高,缺点是切换和调度开销大。

 

有些操作系统是将用户级线程和内核级线程结合,将多个用户线程动态的绑定或映射到一个内核级线程,而一个进程中又包含多个内核级线程,这样可以结合用户线程和内核线程的优点。

内核级线程才是CPU分配的单位。

从创建和切换速度来说,用户级线程高于核心级线程,核心级线程高于进程。

 

 

 

多线程模型

将几个用户级线程映射到几个内核级线程的问题就引出了多线程模型问题。

 

多对一模型:将多个用户级线程映射到一个内核级线程,每个用户进程只有一个内核级线程。

优点:用户级线程的切换在用户态即可完成,不用变态,线程管理的系统开销小。

缺点:并发度不高,一个用户线程阻塞会导致进程阻塞;再者该进程只能被分配到1个CPU,进程内的多线程不能并行只能并发。

 

 

一对一模型:将一个用户级线程映射到一个内核级线程,每个用户进程有多个内核级线程。也就是纯粹在使用内核级线程。

 

优点:并发度高,一个线程阻塞其线程不阻塞;进程内的多线程可以占用多个CPU并行。

缺点:线程切换由OS完成,需要变态,开销大,耗时长。

 

 

多对多模型:将n个用户级线程映射到m个内核级线程(n>=m),每个用户进程有多个内核级线程。它囊括了多对一和一对一模型的优点。




更多内容请关注微信公众号
zbpblog微信公众号

如果您需要转载,可以点击下方按钮可以进行复制粘贴;本站博客文章为原创,请转载时注明以下信息

张柏沛IT技术博客 > 操作系统入门(四)线程概念、与进程的关系和线程模型

热门推荐
推荐新闻