性:
1.模块化, 管程是一个基本程序单位,可以单独编译
2.抽象数据类型, 管程中不仅有数据, 还有对数据的操作
3.信息掩蔽, 管程中的数据结构只能被管程的过程访问, 这些过程也是在管程内部定义的, 共管程外的进程调用, 而管程中的数据结构及过程(函数)的具体实现外部不可见.
管程与进程的对比:
1.管程定义的是公共数据结构, 进程定义的是私有数据结构PCB
2.管程对数据结构进行同步和初始化, 进程则对数据结构进行顺序程序执行
3.管程用于解决共享资源互斥, 进程用于实现系统的并发性
4.管程是被动工作, 进程是主动工作
条件变量
管程的条件变量:条件变量是在管程内部的数据结构,且只有在管程内才能被访问,它对管程内所有过程是全局的,只能通过x.wait(),x.signal()两个操作访问.
x.wait():正在调用的管程因x条件需要被阻塞或挂起, 则调用x.wait()将自己插入到x条件的等待队列上, 并释放管程, 知道x条件变化.
xsignal():正在调用管程的进程发现x发生了变化, 则调用x.siganl(), 重新启动一个因x条件而阻塞或挂起的进程, 如果存在多个这样的进程, 则选择其中的一个, 如果没有则继续执行原进程, 而不产生任何结果.
线程-调度和分派的基本单位
由来:
自古以来熊和鱼掌不可兼得, 同样对于进程来讲, 作为调度和分派的基本单位同时又拥有资源这会加重系统开销. 那么能否将它们分开呢? 对于拥有资源的单位, 并不频繁的进行上下文切换, 于是线程便诞生了.进程作为拥有资源的单位, 线程作为独立调度和分派的单位. 一个进程可拥有多个线程. 在多线程中, 可将每个线程称为一个任务. 宏观上, 进程也是任务.
线程, 有时被称为轻量级进程(Lightweight Process, LWP), 是程序执行流的最小单元.相对的, 传统的进程叫做重型进程.
线程与进程的比较
调度的基本单位:传统OS中, 进程是独立调度和分派的基本单位, 占有资源独立运行, 但是在引入线程的OS中, 线程是调度的基本单位, 可以独立运行的, 此时进程已不是可以独立运行的实体.
并发性:一个进程中拥有多个线程, 称为多线程. 这多个线程可以并发运行.不同进程间的线程也可并发运行.
拥有资源:进程是系统中拥有资源的基本单位, 而线程只有一点必不可少的, 能保证独立运行的资源, 这大大减少了系统的开销.
独立性:每个进程拥有一个独立的地址空间和资源, 除了共享全局变量以外不允许其他进程访问.同一进程中的线程除了只拥有自身必须的少量资源, 它们共享进程的内存地址空间和资源
系统开销:进程因为拥有资源, 每次调度进程时必定要对其分配回收, 系统开销大.线程只占有极少的资源, 其系统开销远低于进程.
线程的三个基本转态
就绪状态: 只要活得cpu就可执行
执行状态: 活得cpu正在执行
阻塞状体: 线程因某种原因受阻而暂停执行
线程控制块TCB
系统为每个进程配置了一个进程控制块PCB用于管理进程.同样, 也有一个线程控制块TCP用户控制和管理线程.它包括:
1.线程标识符: 线程ID
2.寄存器:程序计数器, 状态寄存器, 通用寄存器
3.线程运行状态
4.优先级: 线程的优先级
5.线程专有存储区
6.信号屏蔽
7.堆栈指针