文章目录
第四章:线程
4.1 概述
线程是CPU使用的基本单元,它由线程ID,程序计数器,寄存器集合和栈组成
(每个线程都有属于自己的寄存器,栈等)
一个线程与与它同属一个进程的其它线程共享代码段、数据段和其它操作系统资源(文件等)
下面这张图可以说完美诠释了上面的两句话
4.1.2 优点
多线程有以下几个优点
- 响应度高:如果对一个交互程序采用多线程,那么即使其部分阻塞或执行较冗长
的操作,该程序仍能继续执行,从而增加了对用户的响应程度。 - 资源共享:线程默认共享它们所属进程的内存和资源。
- 经济:进程创建所需要的内存和资源的分配比较昂贵。由于线程能共享它们所属
进程的资源,所以创建和切换线程会更为经济。 - 多处理体系结构的利用:多线程的优点之一是能充分使用多处理器体系结构,
以便每个进程能井行运行在不同的处理器上。
4.2 多线程模型
有两种不同方法来提供线程支持:用户层的用户线程或内核层的内核线程。
用户线程受内核支持,而无须内核管理,而内核线程由操作系统直接支持和管理。
4.2.1 多对一模型
多对一模型将多个用户线程映射到一个内核线程中
4.2.2 一对一模型
一对一模型将每个用户线程映射到一个内核线程
当一个线程执行阻塞系统调用时,另一个线程能继续执行
4.2.3 多对多模型
多对多模型将一些用户线程映射到一些更少数量的内核线程
多对多模型的变种(二级模型)
这种变种多对多模型仍然多路复用了许多用户线程到同样数量或更小数量的内核线程上,但也允许将一个用户线程绑定到某个内核线程上。
4.4 多线程问题
4.4.1 系统调用fork()和exec()
系统调用fork()用于创建独立的、复制的进程
但在多线程程序中,系统调用fork()和exec()的语义有所改变
问题:如果程序中的一个线程调用fork(),那么新进程会复制所有线程,还是新进程只有单个线程?
两种形式都有,要根据具体情况决定使用哪种形式
部分UNIX系统有两种形式的fork()
- 复制所有进程
- 只复制调用了系统调用fork()的进程
如果一个线程调用了系统调用exec(),那么exec()参数所指定的程序会替换整个进程,包括所有线程
上面fork()的两种形式的使用与应用程序(具体情况)有关。
- 如果调用fork()之后立即调用exec(),那么没有必要复制所有线程,因为exec()参数所指定的程序会替换整个进程。在这种情况下,只复制调用线程比较适当。
- 如果在fork()之后另一进程并不调用exec() ,那么另一进程就应复制所有线程。