计算机知识专题(操作系统)——信号量、PV操作、死锁

      作为一个由人工智能上层算法应用转底层计算库优化的小白,最近参考相关博客和书籍,补一补计算机相关基础知识,在此记录下学习的内容,随时更新:

一、基础概念

1、进程:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。

2、进程PCB:系统为了管理进程设置的一个专门的数据结构,用它来记录进程的外部特征,描述进程的运动变化过程。系统利用PCB来控制和管理进程,所以PCB是系统感知进程存在的唯一标志。进程与PCB是一一对应的)。

3、临界区:每个进程中访问临界资源的那段程序称为临界区(临界资源是一次仅允许一个进程使用的共享资源)。每次只准许一个进程进入临界区,进入后不允许其他进程进入。

4、锁:在多线程编程中,操作系统引入了锁机制。通过锁机制,能够保证在多核多线程环境中,在某一个时间点上,只能有一个线程进入临界区代码,从而保证临界区中操作数据的一致性。

5、死锁:一个进程需要独占访问不止一种资源。而操作系统允许多个进程并发致性共享系统资源时,此时可能会出现进程永远被阻塞的现象。这种现象称为死锁。

二、信号量和P、V操作

1、信号量:1965年荷兰的计算机科学家E.W.Dijkstra提出的新的同步工具。他将交通管制中多种颜色的信号灯管理交通的方法引入操作系统,让两个或多个进程通过信号量展开交互。信号量常常用一个记录型数据结构表示,它有两个分项:信号量的值,信号量队列的队列指针。例:信号量是一个二元数组(s,q)。可以这么理解s信号量的状态(一个整数),s的初值不为负数(和交通灯类似)。q是它的等待队列,建立信号量时q为空。

  • s >=0 : 绿灯
  • s < 0 :红灯

2、原语:信号量仅能由同步原语对其进行操作,而原语是执行时不可中断的过程,即原子操作。Dijkstra发明了两个同步原语:P操作和V操作,此外还用的符号有:wait和signal,up和down,sleep和wakeup。利用信号量和P、V操作既可以解决并发进程的的竞争问题,又可以解决进程的协作问题。例:对信号量状态进行改变,P调用一次-1,V调用一次+1。

3、上锁原语:

lock:(w锁位为1,表示已上锁)
{
    while(w == 1)
    {
        保护现场进程CPU现场;
        将现行进程的pcb插入w的等待队列;
        置该进程为“等待”状态;
        转进程调度;
    }
    w = 1;       //上锁
}

4、开锁原语:

lock:(w锁位为1,表示已上锁)
{
    while(w等待队列不为空)
    {
        移除等待队列首元素;
        将现行进程的pcb插入w的就绪队列;
        置该进程为“就绪”状态;
    }
    w = 0;       //开锁
}

5、P操作: 

p(s)是一个原语操作,p操作执行 s– ,若s为负数,调用p(s)的进程被阻塞,放到等待队列q中。

p(s)
{
    s- -;
    if (s < 0)
    {
        保留调用进程的CPU现场;
        将进程的pcb插入到s的等待队列;
        把进程变为“等待状态”;
        转到进程调度;
    }
}

6、V操作 :
v(s)刚好与p(s)操作相反,v操作执行 s++ ,若s为大于0,继续执行;s <=0,从信号灯等待队列移出一个进程,解除等待状态,返回本程序继续执行。

v(s)
{
    s++;
    if (s <= 0)
    {
        移出s等待队列首元素;
        将该进程的pcb插入就绪队列;
        设置该进程为“就绪状态”;
    }
}

四、关于死锁的概念:

1、死锁的原因: 
1)因为系统资源不足。

2)进程运行推进的顺序不合适,保证有先后顺序。

3)资源分配不当等。

2、产生死锁的四个必要条件: 
1)互斥条件:一个资源每次只能被一个进程使用。

2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

3)不剥夺条件: 进程已获得的资源,在末使用完之前,不能强行剥夺。

4)循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。存在一个进程等待序列{P1,P2,…,Pn},其中P1等待P2所占有的某一资源,P2等待P3所占有的某一 源,……,而Pn等待P1所占有的的某一资源,形成一个进程循环等待环。

3、解决死锁的方式. (后续会具体展开)
1)鸵鸟算法:对死锁视而不见。

2)死锁的防止:

(1)破坏死锁的四个必要条件中的任意一个即可防止死锁。(条件一:许多资源不能同时访问,条件三:适用于对主存资源和处理器资源的分配,而不适用于所有资源)

(2)静态分配策略(破坏条件二):一个进程在执行前就申请它所要的全部资源,直到它所要的资源都得到满足后才开始执行。这种策略严重降低了资源利用率。

(3)层次分配策略(破坏条件四):资源被分成多个层次,一个进程得到某一层的一个资源后,它只能再申请在较高一层的资源;当一个进程要释放某层的一个资源时,必须先释放所占用的叫高层的资源,当另一个进程获得了某一层的一次资源后,它想在申请该层中的另一个资源,那么,必须先释放该层中的已占资源。比静态分配在实现上要多花一点代价,但提高了资源使用率。然而,如果一个进咸亨使用资源的次序和系统内的规定各层资源的次序不同时,这种提高可能不明显。

3)死锁的避免:

(1)当不能防止死锁时,如果能掌握并发进程中与每个进程有关的资源申请情况,仍然可以避免死锁的发生。只须在为申请者分配资源前先测试系统状态,若把资源分配给申请者会产生死锁的话,则拒绝分配,否则接受申请,为它分配资源。

(2)银行家算法

4)死锁的检测和恢复:

(1)对资源的分配加以限制可以防止和避免死锁的发生,但这不利于各进程对系统资源的充分共享。解决死锁的另一条途径是死锁检测方法,这种方法对资源的分配不加限制,但系统定时地运行一个“死锁检查”程序,判断系统内是否已出现死锁,若检测到死锁则设法加以解除。(待扩展)

5)混合策略:

(1)在一个操作系统中,为了保证不出现死锁,往往采用死锁的防止、避免和检测的混合策略。对不同类的资源采用不同的调度策略,以使整个系统不出现死锁。

未完待续。。。

 

参考文献:

1、CSDN博客:

https://blog.csdn.net/qicheng777/article/details/77432129

2、操作系统原理与设计书籍:

https://www.jinchutou.com/p-45652747.html

https://max.book118.com/html/2018/0518/167117835.shtm

3、百度百科:

https://baike.baidu.com/item/%E8%BF%9B%E7%A8%8B/382503?fr=aladdin

你可能感兴趣的:(计算机基础)