[操作系统] - 进程关系之同步互斥

同步与互斥

  • 临界区&临界资源

临界资源(Critical Resouce): 一次仅允许一个进程使用的共享资源

临界区(critical section):每个进程中访问临界资源的那段代码

  • 临界区进入的准则

    1. 单个进入
    2. 独自占用
    3. 尽快退出
    4. 落败让权[^6]
  • 进程互斥实现方式

    • 软件

      1. 锁机制

        缺点:让权等待 🙅‍♀️🚫🙅‍♂️


      2. 信号量机制
        整型信号量→ 结构型信号量 → 信号量集

        • 整型信号量
        • 结构型信号量-单信号量
        • 结构型信号量-AND信号量

        • 信号量集


    • 硬件

      1. 关中断

        缺点:过于暴力 🤣😓

      2. TSL、SWAP指令

        缺点:让权等待 🙅‍♀️🚫🙅‍♂️ 无法用于复杂问题🙅‍♂️🚫🙅‍♀️


  • 经典进程的同步问题

    • 生产者—消费者问题
    1678533256061

    回答:两个P操作不能交换次序,要先对资源信号量(如empty)P操作,再对互斥信号量(mutex)进行操作。否则会死锁

    ​ 两个V操作可以交换次序


  • 哲学家进餐问题


  • 读者-写者问题


  • 打瞌睡的理发师问题

    分析

    理发师和每一位顾客各一个进程。

    理发师进程分析:理发师开始工作时,先看一下店内有无顾客,如果没有, 就打瞌睡(阻塞);如果有,就被唤醒,进行理发,且等待人数减1。注:理发师由于不停地理发故使用while循环。

    顾客进程分析:每一位顾客一个进程,故有多个顾客进程。每个进程中,如果顾客数超过座位数,就结束进程。否则等待理发师。顾客理完发(或无座位)就走,因此不需要while循环。

    该问题和生产者-消费者问题相似,但有什么不同?

    满座后,顾客离开店不再排队,即不需要PV

    /*
    引入3 个信号量和一个控制变量:
    控制变量waiting 用来记录等候理发的顾客数,初值为0;
    信号量customers 用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;
    信号量barbers 用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为0;
    信号量mutex 用于互斥,初值为1。
    */
    #define CHAIRS 5
    typedef struct {
        int value;
        struct PCB* list;
    } semaphore;
    semaphore customers = 0;
    semaphore barbers = 0;
    semaphore mutex = 1;
    int waiting = 0;
    
    void barber(void) {
        while (TRUE) {
            P(customers); /*如果没有顾客,则理发师打瞌睡*/
            P(mutex);     /*互斥进入临界区*/
            waiting--;
            V(barbers); /*一个理发师准备理发*/
            V(mutex);   /*退出临界区*/
            cut_hair(); /*理发(在临界区之外)*/
        }
    }
    void customer(void) {
        P(mutex); /*互斥进入临界区*/
        if (waiting﹤CHAIRS) {
            waiting++;
            V(customers); /*若有必要,唤醒理发师*/
            V(mutex);     /*退出临界区*/
            P(barbers);   /*如果理发师正忙着,则顾客打瞌睡*/
            get_haircut();
        } else
            V(mutex); /*店里人满了,不等了*/
    }
    
posted @ 2023-03-11 19:16  LinFeng_Coding  阅读(64)  评论(0编辑  收藏  举报