设置互斥信号量
下面进行详细解释
1. 信号量定义与初始化
semaphore mutex;
mutex = 1; // 初始化为1
- 信号量定义:
semaphore
是定义信号量的类型 ,这里定义了一个名为mutex
的信号量。信号量是一种用于实现进程同步与互斥的机制,本质上是一个特殊变量 。 - 初始化:将
mutex
初始化为1
。在进程互斥场景中,信号量初始值为1
表示临界区当前没有被占用,处于可用状态 。这就好比一间只有一个位置的小房间(临界区),一开始没人(信号量值为 1 ,表示空闲 ) 。
2. 循环结构
while (1)
{// 相关操作
}
while (1)
是一个无限循环,表示进程会不断重复执行循环内的操作 。因为进程在实际运行中,可能会多次需要进入临界区获取资源或执行关键代码,所以用无限循环来模拟这个持续的过程 。就像一个人可能会多次需要进入小房间做事情 。
3. wait 操作
wait(mutex);
wait
操作是信号量机制中的一个原语 ,也称为 P 操作。当进程执行到 wait(mutex)
时:
- 首先会将信号量
mutex
的值减1
,即mutex = mutex - 1
。 - 然后检查
mutex
的值 ,如果mutex
的值大于等于0
,说明在执行wait
操作前,临界区是空闲的或者虽然有进程在使用临界区,但还有剩余的 “进入许可”(这里信号量值大于 0 ,可以理解为有额外的进入许可 ) ,那么当前进程可以进入临界区 ;如果mutex
的值小于0
,说明在执行wait
操作前,临界区已经被其他进程占用,没有剩余的 “进入许可” 了,此时当前进程会被阻塞 ,放入与该信号量相关的等待队列中,等待其他进程释放临界区资源 。这就好比一个人到小房间门口,先看有没有人,如果没人或者有多余的进入机会(信号量大于等于 0 ) ,就可以进去;如果已经有人在里面(信号量小于 0 ) ,就得在门口等着 。
4. 临界区
临界区;
临界区是指进程中访问临界资源的那段代码 。临界资源是一次仅允许一个进程访问的资源,比如共享变量、文件等 。在这个小房间(临界区)里,进程可以对共享资源进行操作 ,比如读取或修改共享变量的值 。由于同一时间只能有一个进程进入临界区,所以保证了对临界资源访问的安全性和一致性 ,避免多个进程同时访问临界资源导致数据混乱 。
5. signal 操作
signal(mutex);
signal
操作是信号量机制中的另一个原语 ,也称为 V 操作。当进程执行完临界区的操作后,会执行 signal(mutex)
:
- 首先将信号量
mutex
的值加1
,即mutex = mutex + 1
。 - 然后检查
mutex
的值 ,如果mutex
的值大于0
,说明在执行signal
操作前,没有进程在等待进入临界区 ,只是简单地释放了一个 “进入许可” ;如果mutex
的值小于等于0
,说明在执行signal
操作前,有进程因为等待进入临界区而被阻塞在等待队列中 ,此时会从等待队列中唤醒一个进程 ,让其有机会进入临界区 。这就好比一个人从小房间出来后(执行完临界区操作 ) ,告诉在门口等待的人(等待队列中的进程 ) ,现在可以进去了(唤醒等待的进程 ) 。
6. 剩余区
剩余区;
剩余区是进程中除临界区以外的代码部分 。在进程执行完临界区的操作,释放临界区资源(执行 signal
操作 )后,就进入剩余区执行其他非关键代码 。这部分代码不涉及对临界资源的访问,所以多个进程可以并行执行剩余区的代码 。就像一个人从小房间出来后,去做其他不影响小房间使用的事情 。
总体而言,这段代码通过信号量 mutex
以及 wait
和 signal
操作,实现了多个进程对临界区的互斥访问 ,保证了同一时间只有一个进程能够进入临界区访问临界资源 。