• 用信号量实现进程互斥, 同步, 前驱关系


    在这里插入图片描述
    回顾:

    信号量
    对应一种资源
    信号量的value:
    资源的剩余数量
    如果小于0表示有进程在等待该资源
    P操作:
    申请一个资源
    如果资源不够就阻塞该进程
    V操作
    释放一个资源
    并检查是否仍有进程等待该资源, 有则唤醒一个进程

    实现进程互斥

    步骤

    1. 确定临界区
      即确定哪段代码用于访问临界资源

    2. 设置 互斥信号量 mutex, 并初始化

    3. 进入区进行P(mutex)操作以申请资源
      回顾进程互斥的四个逻辑部分
      在这里插入图片描述

    4. 退出区进行V(mutex)操作以释放资源
      在这里插入图片描述

    英文翻译:
    mutex: 互斥体
    semaphore: 信号量
    
    使用semaphore mutex方式定义信号量一般认为是记录型信号量
    typedef struct {
    	int value;
    	struct process *L;
    }semaphore;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    注意事项

    1. 使用semaphore mutex方式定义信号量一般认为是记录型信号量
    2. 对于不同的临界资源需要设置不同的互斥信号量
    3. PV操作必须成对出现
      缺少P则无法保证临界资源的互斥访问
      缺少V则导致资源无法被释放, 且等待进程无法被唤醒

    实现进程同步

    回顾

    什么是进程同步?
    由于进程的并发执行导致的异步的特性, 我们无法确定不同进程中指令的执行顺序
    为什么需要进程同步?
    比如进程1的指令1必须要在进程2的指令3后面执行, 这时候就需要我们提供进程同步机制来实现

    如何利用PV操作来实现进程同步?

    考虑P操作中资源数为0时的情况
    在这里插入图片描述
    先对value–, 然后发现value<0, 该进程阻塞

    所以我们可以利用如上特性, 阻止代码的执行

    实现进程同步的步骤

    1. 确定需要进行进程同步的地方,
      即哪部分要在前面执行,
      哪部分要在后面执行

    2. 设置同步信号量S, S.value初始化为0

    3. 添加PV操作
      先执行的代码的末尾添加V(S)操作
      后执行的代码的开头添加P(S)操作

    semaphore S = 0;
    
    P1 ( ) {
    	代码1;
    	代码2;
    	V(S);
    	代码3;
    }
    
    P2 ( ) {
    	P(S);
    	代码4;
    	代码5;
    	代码6;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    如上代码中, 代码1,2必然在代码4,5前执行

    在没有执行V(S)之前, S=0, 直接执行P(S)
    会阻塞该进程

    除非执行了V(S)使得S.value++后才能顺利执行P(S)以后的内容

    实现进程的前驱关系

    利用进程同步中得到的总结:
    先执行的代码的末尾添加V(S)操作
    后执行的代码的开头添加P(S)操作
    在这里插入图片描述

    图中:

    • Sn为Pn进程中的某个指令
    • x—>y表示x在y前执行
    • abcdefg分别为自己创建的信号量且他们的value初始都为0
    • V(a)—>P(a)表示在S1执行末尾添加V(a)操作, 在S2开始前添加P(a)操作, 其他同理

    总结

    在这里插入图片描述
    使用信号量实现进程同步与进程的前驱关系时, 特别要注意总结出来的结论:

    1. 先执行的代码的末尾添加V(S)操作
    2. 后执行的代码的开头添加P(S)操作
  • 相关阅读:
    短信登录实现(黑马点评为例)
    Java 网络编程
    小程序无感刷新
    【Centos7】解决 CentOS 7 中出现 “xx: command not found“ 错误的全面指南
    Spring Boot 配置文件这样加密,才足够安全!
    python3 修行之基础篇(一)python 简介
    【R语言】R语言的管道操作符 %>%, %T>%, %$% 和 %<>%
    【opencv450-samples】intersectExample.cpp凸凸多边形求交:得到重叠区域及面积
    PCL1.12.1点云可视化学习(二)
    【关注】国内外经典大模型(ChatGPT、LLaMA、Gemini、DALL·E、Midjourney、文心一言、千问等
  • 原文地址:https://blog.csdn.net/weixin_45575944/article/details/126440728