进程管理
进程特征
结构
程序是一组有序指令的集合,静态的存放于某种介质。为使程序能独立运行,配置一进程控制块PCB(Process Control Block),由程序段,数据段和PCB三部分便构成了进程实体。所谓创建进程,实质上是创建进程实体中的PCB,撤销进程,实质上是撤销进程的PCB
动态性
进程的实质是进程实体的一次执行过程,由创建而产生,由调度而执行,由撤销而消亡。
并发性
多个进程实体同时存在于内存中,且能在一段时间内同时运行。程序(没有PCB)是不能并发执行的。
独立性
进程实体是一个能独立运行,独立分配系统资源和独立接收调度的基本单位。
异步性
进程按各自独立的,不可预知的速度向前推进,或者说进程是按异步方式运行的。
进程三种基本状态
进程执行时的间断性决定了进程具有多种状态。
就绪状态
进程已分配到除CPU以外的所有必要资源(内存,I/O设备),只要获取CPU,便可立即执行。此时为就绪状态,存在于就绪队列
执行状态
进程获得CPU,正在执行。单处理机中只有一个进程处于执行状态,多处理机中有多个进程处于执行状态。
阻塞状态
正在执行的进程由于发生某事件(请求I/O,申请缓冲区,访问临界资源)而暂时无法继续执行,便放弃处理机而处于阻塞状态。存在于阻塞队列。
创建状态
为一个新进程创建PCB,并填写必要管理信息,把进程转入就绪状态并插入就绪队列中。
终止状态
当一个进程到达了自然结束点,或是出现了致命错误,或是被OS终结,将进入终止状态。 等待操作系统进行善后处理,然后将其PCB清零,并将PCB空间返还系统。
挂起状态
原因:
- 终端用户请求,终端用户可在自己程序运行期间发现问题,暂时使程序静止
- 父进程请求,父进程挂起子进程
- 负荷调节需要,系统中工作负荷较重,可能影响到对实时任务的控制时,可由系统把一些不重要的进程挂起
- 操作系统需要
进程控制块
- 作用
1.PCB用于描述和控制进程的运行,linux中用task_struct数据结构来描述每个进程的进程控制块。
2.系统将所有PCB组织成若干个链表或队列,存放在OS中专门开辟的PCB区内。 - 基本信息
1.进程标识符,唯一标识一个进程。
2.处理机状态
3.进程调度信息,进程状态,进程优先级,其他信息
4.进程控制信息,程序和数据地址,进程同步和通信机制,资源清单,链表指针,指向下一个PCB的首地址。
进程
进程创建
- 进程图 用于描述一个进程家族关系的有向树。子进程可以继承父进程所拥有的资源,如继承父进程打开的文件,继承父进程所分配的缓冲区等。
- 进程创建
1.申请空白PCB。申请唯一标识符,并从PCB集合中索取一个空白PCB
2.为新进程分配资源。
3.初始化进程控制块
4.将新进程插入就绪队列。 - 进程终止,引起进程终止的事件
1.正常结束
2.异常结束,越界错误,非法指令,等 - 进程的阻塞和唤醒
1.请求系统服务,如访问已分配给其他进程的打印机。如访问被锁住的共享资源
2.启动某种操作。如I/O设备
3.新数据未到达,阻塞等待。
4.等待新任务。
阻塞过程,进程阻塞式进程自身的一种主动行为。利用block原语(原子操作)把进程控制块中的状态改为阻塞,并将PCB插入阻塞队列。
唤醒过程,当被阻塞进程期待的时间出现时,如I/O完成或网络数据到达,由相关进程的调用唤醒原语唤醒。首先把阻塞的进程从等待时间的阻塞队列移除,将PCB状态改为就绪,插入就绪队列等待调度。
线程
- 操作系统引入进程的目的,是为了使多个程序能并发执行,以提高资源利用率和系统吞吐量。线程则是为了减少程序在并发执行时所付出的空间切换开销,使OS具有更好的并发性。
- 进程:1.拥有资源的独立单位 2.可独立调度和分派的单位 为使程序能并发执行,系统还必须进行1.创建进程,撤销进程,进程切换操作。切换时需要保留当前进程CPU环境和新进程CPU环境,系统必须为此付出较大的时间空间开销。所以在系统中所设置的进程数目不宜过多,进程切换频率不宜过大,就限制了并发程度的进一步提高。
- 把进程的2个属性分开处理,提供并发性。线程作为调度和分派的基本单位,但不作为拥有资源的单位。
- 进程至少有一个线程。
线程特性
轻型实体
包括一些必不可少的,保证其独立运行的资源。线程控制块TCB,用于指示被执行指令序列的程序计数器,保留局部变量,少数状态参数和返回地址等的一组寄存器和堆栈。
独立调度和分派的基本单位
线程是很轻量级的,线程切换非常迅速且开销小
可并发执行
一个进程中的多个线程,不同进程中的线程都能并发执行
共享进程资源
进程中的线程都具有相同的地址空间,可以访问进程所拥有的文件,定时器,信号量等
线程状态
如传统进程一样,各线程间也存在共享资源和相互合作制约,使得线程也是间断性的往前推进运行。
1.执行状态,线程正获得处理机而运行
2.就绪状态,线程已具备各种资源(内存,I/O设备),获得CPU便可执行
3.阻塞状态
多线程OS中的进程
1.作为系统资源分配的单位。资源包括:受到保护的用户地址空间,用于实现进程间和线程间同步和通信的机制,已打开的文件和已申请到的I/O设备,以及一张由核心进程维护的地址映射表,该表用于实现用户程序的逻辑地址到其内存物理地址的映射。
2.可包括多个线程。进程为线程提供资源及运行环境,使得线程可并发执行
3.进程不再是一个可执行实体。多线程OS中,是把线程作为独立运行的基本单位。
线程和进程比较
调度
- 线程作为可调度和分派的单位能够提高系统并发性
- 同一个进程中,线程切换不会引起进程切换,但从一个进程的线程切换到另一个进程的线程,会引起进程切换。
并发性
进程间可以并发执行,一个进程中的多个线程之间也可以并发执行,使得操作系统具有更好的并发性,提高系统资源的利用率和吞吐量。
拥有资源
进程拥有资源,是系统中拥有资源的基本单位。进程中的线程不拥有资源,但可访问隶属进程的资源,如一个进程的代码段,数据段和所拥有的系统资源,打开的文件,I/O设备等。
系统开销
- 创建和撤销进程时,系统创建和回收进程控制块,分配回收资源的开销明显大于线程创建或撤销的开销。
- 线程切换仅需保存和设置少量寄存器内容,不涉及存储器管理方面操作
- 一个进程中的多个线程具有相同的地址空间,在同步和通信的实现比进程容易。
线程同步和通信
互斥锁(mutex)
互斥锁是一种简单的,用于实现线程间对资源互斥访问的机制,保证对临界资源的互斥访问。一个线程访问共享数据时,首先对该数据设置mutex执行关锁命令,如果已处于关锁,则线程被阻塞。
容易发生死锁:
1.同一个线程先后两次Lock,第二次由于锁已经被自己占用,该线程会等待释放锁,由于已被挂起没机会释放锁,将会一直处于等待状态。
2.线程A对mutex1关锁,进入临界区C,若在C内该线程又访问临界资源R,此时线程B已经访问R,并对mutex2关锁,线程A进入阻塞,如果线程B也要进入临界区C,但mutex1被线程A锁住。这样就形成了相互等待,死锁。
条件变量
为了解决死锁问题,引入条件变量,每一个条件变量通常与一个互斥锁使用。互斥锁用于短期锁定,保证临界区的互斥访问,条件变量用于线程的长期等待,直至所等待的资源成为可用。
process_msg(void)
{
struct msg *mp;
for (;;) {
pthread_mutex_lock(&qlock);
while (workq == NULL)
pthread_cond_wait(&qready, &qlock);
mp = workq;
workq = mp->m_next;
pthread_mutex_unlock(&qlock);
/* now process the message mp */
}
}
void
enqueue_msg(struct msg *mp)
{
pthread_mutex_lock(&qlock);
mp->m_next = workq;
workq = mp;
pthread_mutex_unlock(&qlock);
pthread_cond_signal(&qready);
}
pthread_cond_wait 作用是把调用线程放到条件等待队列,释放mutex,且是原子操作。唤醒的只能是在条件变量上等待的某一个线程,其他线程继续等待。 参考:https://www.cnblogs.com/harlanc/p/8596211.html#_label2_0
- 原文作者:niep
- 原文链接:http://www.fdgggy.com/2019/10/15/process/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。