本文内容整理自西安交通大学软件学院田丽华老师的课件,仅供学习使用,请勿转载
操作系统系列笔记汇总:操作系统笔记及思维导图汇总附复习建议_Qlz的博客-CSDN博客
文章目录
Overview
进程
进程具有二个基本属性:
- 是一个拥有资源的独立单位:它可独立分配虚地址空间、主存和其它
- 是一个可独立调度和分派的基本单位
由于进程是一个资源的拥有者,因而在进程创建、撤销、调度切换时,系统需要付出较大的时空开销。进程的数目不宜过多,进程切换频率不宜过高,限制了并发程度。
引入线程的目的是简化进程间的通信,以小的开销来提高进程内的并发程度。
线程
线程作为CPU调度单位,而进程只作为其他资源分配单位
- 只拥有必不可少的资源,如:线程状态、程序计数器、寄存器上下文和栈
- 同样具有就绪、阻塞和执行三种基本状态
- 与同属一个进程的其它线程共享进程拥有的全部资源
- 可并发执行
优点
- 线程的优点:减小并发执行的时间和空间开销(线程的创建、退出和调度),因此容许在系统中建立更多的线程来提高并发程度。
- 线程的创建时间比进程短;
- 线程的终止时间比进程短;
- 同进程内的线程切换时间比进程短;
- 由于同进程内线程间共享内存和文件资源,可直接进行不通过内核的通信;
基本概念
- A thread (or lightweight process) is a basic unit of CPU utilization; it consists of:
线程(轻型进程)是CPU运用的一个基本单元,包括- program counter 程序计数器
- register set 寄存器集
- stack space 栈空间
- A thread shares with its peer threads its:
一个线程与它的对等线程共享:- code section 代码段
- data section 数据段
- operating-system resources 操作系统资源
- A traditional or heavyweight process is equal to a task with one thread
传统的或重型进程等价于只有一个线程的任务
进程和线程的比较
- 并发性:在引入线程的OS中,不仅进程之间可以并发执行,而且在一个进程中的多个线程之间亦可并发执行,因而使OS具有更好的并发性,从而能更有效地使用系统资源和提高系统吞吐量。
- 拥有资源:进程是拥有资源的独立单位
- 系统开销:在创建或撤消进程时,系统都要为之分配或回收资源,如内存空间、I/O设备等。因此,OS所付出的开销将明显地大于在创建或撤消线程时的开销。
- 地址空间和其他资源(如打开文件):进程间相互独立,同一进程的各线程间共享--某进程内的线程在其他进程不可见
- 通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信--需要进程同步和互斥手段的辅助,以保证数据的一致性
- 调度:线程上下文切换比进程上下文切换要快得多;
Benefits
-
Responsiveness
响应度高:一个多线程的应用在执行中,即使其中的某个线程阻塞,其他的线程还可继续执行,从而提高响应速度 -
Resource Sharing
资源共享:同一进程的多个线程共享该进程的内存等资源 -
Economy
经济性:创建和切换线程的开销要低于进程。比如,Solaris中进程创建时间是线程创建的30倍,进程切换时间是线程切换的5倍。
-
Utilization of MP Architectures
MP体系结构的运用:多线程更适用于多处理机结构。 -
在一个多线程任务中,当一个服务器线程被阻塞后,在同一个任务中的第2个线程可运行
-
同一作业中多线程协同导致高吞吐量并改善性能
-
应用程序需要共享一个公用的缓冲(即生产者-消费者),从线程运用中得利
-
线程提供了一种机制,允许序列进程阻塞系统调用同时还能实现并发
User and Kernel Threads
-
**Kernel-supported threads ** 内核支持的线程 (Mach and OS/2).
-
User-level threads; supported above the kernel, via a set of library calls at the user level (Project Andrew from CMU).
用户级线程;在内核之上,通过用户级的库调用
-
Hybrid approach implements both user-level and kernel-supported threads (Solaris 2). 混合处理实现用户级和内核支持线程
Kernel Threads
依赖于OS核心,由内核的内部需求进行创建和撤销,用来执行一个指定的函数
- Supported by the Kernel
- 由内核支持,在内核空间执行线程创建、调度和管理
- Thread is unit of CPU scheduling
- 内核维护进程和线程的上下文信息;
- 线程切换由内核完成;
- 一个线程发起系统调用而阻塞,不会影响其他线程的运行。
- 时间片分配给线程,所以多线程的进程获得更多CPU时间。
- 例子
- Windows XP/2000
- Solaris
- Digital UNIX
User Threads
不依赖于OS核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。调度由应用软件内部进行,通常采用非抢先式和更简单的规则,也无需用户态/核心态切换,所以速度特别快。
- Thread Management Done by User-Level Threads Library
- 由用户级线程库进行管理的线程
- 线程库提供对线程创建\调度和管理的支持,无需内核支持。
- Process is still unit of CPU scheduling from OS kernel perspective
- 用户线程的维护由应用进程完成;
- 内核不了解用户线程的存在;
- 用户线程切换不需要内核特权;
- 用户线程调度算法可针对应用优化;
- DRAWBACKS
- 如果内核是单线程的,那么一个用户线程发起系统调用而阻塞,则整个进程阻塞。
- 时间片分配给进程,多线程则每个线程就慢。
对比
- 调度方式:内核线程的调度和切换与进程的调度和切换十分相似,用户线程的调度不需OS的支持。
- 调度单位:用户线程的调度以进程为单位进行,在采用时间片轮转调度算法时,每个进程分配相同的时间片。对内核级线程,每个线程分配时间片。
Multithreading Models
- Many-to-One 多对一
- One-to-One 一对一
- Many-to-Many 多对多
Many-to-One多对一
- 多个用户级线程映像进单个内核线程
- 用于不支持内核线程的系统中
- 任一时刻只能有一个线程可以访问内核(并发性低)
- 一个用户线程发起系统调用而阻塞,则整个进程阻塞。
One-to-One一对一
- 每个用户级线程映像进内核线程
- 提供了更好的并发性,一个用户线程发起系统调用而阻塞时允许另一个线程运行
- 每创建一个用户级线程需创建一个相应的内核线程,带来了额外开销,所以许多系统限制应用中的线程数目
- 例子
- Windows 95/98/NT
- OS/2
Many-to-many Model多对多模型
- 多对一模型的缺点:不能实现真正的并发
- 一对一模型的缺点:需限制应用中的线程数目
- 多对多模型:不限制应用的线程数、多个线程可以并发
Two-level Model
Similar to M:M, except that it allows a user thread to be bound to kernel thread
Threading Issues
Semantics of fork( ) and exec( ) system calls
fork
is used to create a separate, duplicate process- in multithreaded program, some UNIX have two versions of fork:
- duplicate all threads in the process 复制所有线程
- used when no following exec call
- duplicate only the thread calling fork只复制调用fork的线程
- used when a immediately followed exec call
- duplicate all threads in the process 复制所有线程
exec
参数所指定的程序会替换整个进程
Thread cancellation
- target thread: the thread to be cancelled
- asynchronous cancellation异步取消:
- one thread immediately terminates the target thread一个线程立即终止目标线程
- may be cancelled in the middle of updating data shared with other threads
- may not free a system-wide resource
- deferred cancellation延迟取消:
- the target thread can periodically check if it should terminate (at so called cancellation points in Pthread)目标线程检查它是否应该终止
Signal handling
- 当特定事件发生时,一般会给进程发送信号来通知
- 信号可以被同步或异步的接收
- 同步信号会发送到产生信号的同一个进程。比如,非法内存访问,或者除零错。
- 当信号是由运行进程之外的事件所产生 ,那么进程就异步的接收信号。比如,定时器中断或者ctrl+C。
- 单线程进程中,信号总是发送给进程
- 多线程进程中
- 同步信号需要发送到产生信号的线程,而不是进程中的其他线程
- 异步信号
- the thread to which the signal applies 信号应用的线程
- every thread in the process 进程中的所有线程
- certain threads in the process 进程的某些线程
- a specific thread to receive all signals 一个特定线程用来接收所有信号
Thread pools
- 为什么要线程池
- 避免创建和撤销开销
- 限制线程的数量
- Main idea of thread pools
- considerations
- number of CPUs
- amount of physical memory
- expected number of concurrent requests
Thread specific data
- threads belonging to a process share the data of that process
- thread-specific data 线程特定数据 is a independent copy of certain data owned by one thread
- example
- in a transaction processing system, service each transaction in a separate thread
- transaction ID to each thread
- supported in most thread libraries including Win32, Pthreads, Java
举例
SUN Solaris 2
- Solaris支持内核线程(Kernel threads)、轻权进程(Lightweight Processes)和用户线程(User Level Threads)。一个进程可有大量用户线程;大量用户线程复用少量的轻权进程,不同的轻权进程分别对应不同的内核线程。
- LWP在用户级线程和内核级线程之间层次
线程需要的资源
- 内核线程:小数据结构及栈;线程切换不需要内存访问信息 - 相对快
- LWP: PCB with register data, accounting and memory information,; switching between LWPs is relatively slow.
LWP:带有寄存器数据的PCB,记账和内存信息;在LWP之间切换相对慢 - 用户级线程:只需栈及程序计数器;无内核涉及所以切换快。内核只关注支持用户级线程的LWP
轻权进程(LightWeight Process)
它是内核支持的用户线程,是内核数据结构,驻留在内核空间。一个进程可有一个或多个轻权进程,每个轻权进程由一个单独的内核线程来支持。
LWP允许一个进程中发出多个并发的系统调用(因为有多个线程)
Without LWPs, user threads would contend(竞争) at system call
- 用户级线程在使用系统调用时(如文件读写),需要“捆绑(bound)”在一个LWP上。
- 永久捆绑:一个LWP固定被一个用户级线程占用,该LWP移到LWP池之外
- 临时捆绑:从LWP池中临时分配一个未被占用的LWP
- 对于没有绑定的LWP,则由线程库动态地进行调整:
- 一个进程对应的LWP组成LWP池,线程库动态调整池中LWP的数目,以保证应用的最佳性能:
- 当池中的LWP全部阻塞,而进程中还有线程可以运行,则线程库会为之创建另一个LWP;
- 当一个LWP长时间没用(老化,一般为5分钟),则线程库会删除它。
- 一个进程对应的LWP组成LWP池,线程库动态调整池中LWP的数目,以保证应用的最佳性能:
- 在使用系统调用时,如果所有LWP已被其他用户级线程所占用(捆绑),则该线程阻塞直到有可用的LWP--例如6个用户级线程,而LWP池有4个LWP
- 如果LWP执行系统调用时阻塞(如read()调用),则当前捆绑在LWP上的用户级线程也阻塞。