临界资源: 一个时间段内只允许一个进程使用地资源.
进程同步
并发性带来了异步性, 有时需要通过进程同步解决这种异步问题.
有的进程之间需要相互配合地完成工作, 各进程的工作推进需要遵循一定的先后顺序.
进程互斥
对临界资源的访问, 需要互斥的进行. 即同一时间段内只允许一个进程访问该资源.
四个部分
进入区: 检查是否可进入临界区, 若可进入, 需要上锁
临界区: 访问临界资源的那段代码
退出区: 负责解锁
剩余区: 其余代码部分
需要遵循的原则
空闲让进: 临界资源空闲时, 应允许一个进程访问
忙则等待: 临界区正在被访问时, 其他试图访问的进程需要等待
有限等待: 要在有限时间内进入临界区, 保证不会饥饿
让权等待: 进不来临界区的进程, 要释放处理机, 防止忙等
进程互斥的软件实现方法
单标志法:
两个进程在访问完临界区后会把使用临界区的权限转交给另一个进程. 也就是说每个进程进入临界区的权限只能被另一个进程赋予.
不满足 "空闲让进"
双标志先检查法:
每个进程进入临界区之前先检查当前有没有别的进程想进入临界区, 如果没有, 则把自身对应的标志设为 true, 之后开始访问临界区.
不满足 "忙则等待"
双标志后检查法:
前一个算法的问题是先 "检查" 后 "上锁", 但是这两个操作又无法一气呵成, 因此导致两个进程同时进入临界区的问题. 因此, 改为先 "上锁" 后 "检查" 的方法.
不满足 "空闲让进" 和 "有限等待"
Peterson:
在进入区 "主动争取 - 主动谦让 - 检查对方是否想进, 己方是否谦让"
不满足 "让权等待"
进程互斥的硬件实现方法
中断屏蔽方法:
进入临界区之前关中断, 即不允许当前进程被中断, 也必然不会发生进程切换.
退出临界区之后开中断, 当前进程访问完临界区, 再执行开中断指令, 才有可能有别的进程上处理机并访问临界区.
缺点: 一旦中断被禁用, 进程就无法被停止. 不适用于多 CPU, 不适用于用户进程(因为开关中断指令只能运行在内核态).
TestandSet:
原子操作指令 --TestandSet:1. 从内存中读取值 2. 测试该值是否为 1 并返回真或假 3. 内存值设置为 1
不满足让权等待
Swap:
原则操作指令 --Swap: 交换内存中的两个值
不满足让权等待
信号量机制
信号量(抽象数据类型): 是一个变量, 可以用来表示系统中某种资源的数量.
一个整型(sem), 两个原子操作
P 操作 (wait() 原语):
sem 减 1, 如果 sem < 0, 等待, 否则继续
一定是先 sem --, 之后可能需要执行 block 原语
V 操作 (signal() 原语):
sem 加 1, 如果 sem <= 0, 唤醒一个等待的 P
一定是先 sem ++, 之后可能需要执行 wakeup 原语
信号量机制实现进程互斥和同步
管程
目的: 解决信号量机制存在的编写程序困难, 易出错的问题.
管程的组成
共享数据结构
对数据结构初始化的语句
一组用来访问数据结构的过程(函数)
管程的基本特征:
各外部进程 / 线程只能通过管程提供的特定 "入口" 才能访问共享数据.
每次仅允许一个进程在管程内执行某个内部过程.
各进程必须互斥的访问管程的特性是由编译器实现的.
可在管程中设置条件变量及等待 / 唤醒操作以解决同步问题.
来源: https://www.cnblogs.com/xiaobaizzz/p/12285226.html