进程、线程、协程
一、概念与区分
1、进程
- 进程是程序一次动态执行的过程,是程序运行的基本单位。
- 每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。
- 进程占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、页表、文件句柄等)比较大,但相对比较稳定安全。协程切换和协程切换
2、线程
- 线程又叫做轻量级进程,是CPU调度的最小单位。
- 线程从属于进程,是程序的实际执行者。一个进程至少包含一个主线程,也可以有更多的子线程。
- 多个线程共享所属进程的资源,同时线程也拥有自己的专属资源。
- 程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。
3、协程
- 协程是一种用户态的轻量级线程,协程的调度完全由用户控制。
- 一个线程可以拥有多个协程,协程不是被操作系统内核所管理,而完全是由程序所控制。
- 与其让操作系统调度,不如我自己来,这就是协程。
通信方式
进程间通信(7种) |
管道 | 半双工(即数据只能在一个方向上流动),具有固定的读端和写端 只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间) 通过内核缓冲区实现数据传输 |
---|---|---|
有名管道 | 有名管道以磁盘文件的方式存在,在系统中有对应的路径 可以实现本机任意两个进程通信。 管道的本质是内核维护了一块缓冲区与管道文件相关联,对管道文件的操作 被内核转换成对这块缓冲区内存的操作。 |
|
信号(Signal) | 通知接收进程某个事件已经发生 | |
信号量(PV) | 信号量是一个计数器,用于多进程对共享数据的访问的同步 进程对信号量的操作都是原子操作 |
|
消息队列 | 消息的链表,是一系列保存在内核中消息的列表 其优势是对每个消息指定特定的消息类型,接收的时候不需要按照队列次序,而是可以根据自定义条件接收特定类型的消息。 |
|
共享内存 | 使得多个进程可以访问同一块内存空间 多个进程将同一块物理内存(用户空间)映射到自己的虚拟地址空间当中 |
|
套接字 | 此方法主要用于在客户端和服务器之间通过网络进行通信 | |
线程间通信(3种) | 互斥量(锁) | 只有拥有互斥量的线程才能执行任务 | | | 信号量(PV) | 信号量是一个计数器 | | | 事件 | 事件机制,允许一个线程在处理完一个任务后,主动唤醒另外一个线程执行任务。 |
线程的生命周期
- 创建:线程从创建到被cpu执行之前的这个阶段。
- 就绪:指线程已具备各种执行条件,一旦获取cpu便可执行。
- 运行:表示线程正获得cpu在运行。
- 阻塞:指线程在执行中因某件事而受阻,处于暂停执行的状态,阻塞的线程不会去竞争cpu。
- 终止:线程执行完毕,接下来会释放线程占用的资源。
进程调度算法
一、先到先服务
先来先去服务调度算法是一种最简单的调度算法,也称为先进先出或严格排队方案。当每个进程就绪后,它加入就绪队列。当前正运行的进程停止执行,选择在就绪队列中存在时间最长的进程运行。该算法既可以用于作业调度,也可以用于进程调度。
二、最短进程优先
最短进程优先是一个非抢占策略,他的原则是下一次选择预计处理时间最短的进程,因此短进程将会越过长作业,跳至队列头。该算法即可用于作业调度,也可用于进程调度。但是他对长作业不利,不能保证紧迫性作业(进程)被及时处理,作业的长短只是被估算出来的。
三、时间片轮转法
轮转法是基于适中的抢占策略的,以一个周期性间隔产生时钟中断,当中断发生后,当前正在运行的进程被置于就绪队列中,然后基于先来先去服务策略选择下一个就绪作业的运行。这种技术也称为时间片,因为每个进程再被抢占之前都给定一片时间。
四、优先级调度
在进程等待队列中选择优先级最高的来执行
五、多级反馈队列调度算法
多级反馈队列算法,不必事先知道各种进程所需要执行的时间,他是当前被公认的一种较好的进程调度算法。其实施过程如下:
1)设置多个就绪队列,并为各个队列赋予不同的优先级。在优先权越高的队列中,为每个进程所规定的执行时间片就越小。
2)当一个新进程进入内存后,首先放入第一队列的末尾,按照先到先服务原则排队等候调度。如果他能在一个时间片中完成,便可撤离;如果未完成,就转入第二队列的末尾,同样等待调度…..如此下去,当一个长作业(进程)从第一队列依次将到第n队列(最后队列)后,便按第n队列时间片轮转运行。
3)仅当第一队列空闲的时候,调度程序才调度第二队列中的进程运行;仅当第1到(i-1)队列空时,才会调度第i队列中的进程运行,并执行相应的时间片轮转。
4)如果处理机正在处理第i队列中某进程,又有新进程进入优先权较高的队列,则此新队列抢占正在运行的处理机,并把正在运行的进程放在第i队列的队尾。
死锁
死锁产生的条件
1 互斥条件
指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
2 请求和保持条件
进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程堵塞,但又对自己已获得的其他资源保持不放。
3 不剥夺条件
指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
4 环路等待条件
指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。
破坏死锁的方法
1 破坏互斥条件
方法: 如果允许系统资源都能共享使用,则系统不会进入死锁状态。
缺点: 有些资源根本不能同时访问,如打印机等临界资源只能互斥使用。所以,破坏互斥条件而预防死锁的方法不太可行,而且在有的场合应该保护这种互斥性。
2 破坏请求并保持条件
方法: 釆用预先静态分配方法,即进程在运行前一次申请完它所需要的全部资源,在它的资源未满足前,不把它投入运行。一旦投入运行后,这些资源就一直归它所有,也不再提出其他资源请求,这样就可以保证系统不会发生死锁。
缺点: 系统资源被严重浪费,其中有些资源可能仅在运行初期或运行快结束时才使用,甚至根本不使用。而且还会导致“饥饿”现象,当由于个别资源长期被其他进程占用时,将致使等待该资源的进程迟迟不能开始运行。
3 破坏不可剥夺条件
方法: 当一个已保持了某些不可剥夺资源的进程,请求新的资源而得不到满足时,它必须释放已经保持的所有资源,待以后需要时再重新申请。这意味着,一个进程已占有的资源会被暂时释放,或者说是被剥夺了,或从而破坏了不可剥夺条件。
缺点:该策略实现起来比较复杂,释放已获得的资源可能造成前一阶段工作的失效,反复地申请和释放资源会增加系统开销,降低系统吞吐量。这种方法常用于状态易于保存和恢复的资源,如CPU的寄存器及内存资源,一般不能用于打印机之类的资源。
4 破坏循环等待条件
方法: 为了破坏循环等待条件,可釆用顺序资源分配法。首先给系统中的资源编号,规定每个进程,必须按编号递增的顺序请求资源,同类资源一次申请完。也就是说,只要进程提出申请分配资源Ri,则该进程在以后的资源申请中,只能申请编号大于Ri的资源。
缺点: 这种方法存在的问题是,编号必须相对稳定,这就限制了新类型设备的增加;尽管在为资源编号时已考虑到大多数作业实际使用这些资源的顺序,但也经常会发生作业使用资源的顺序与系统规定顺序不同的情况,造成资源的浪费;此外,这种按规定次序申请资源的方法,也必然会给用户的编程带来麻烦。