wait和signal是记录型信号量机制中用于实现进程同步与互斥的两个重要操作,
wait 操作
wait(semaphores *S) {
    S->value --;
    if (S->value<0) block(S->list)
}- 请求资源 :S->value --;这一步表示进程请求一个单位的资源,将信号量S的value值减 1 。比如信号量原本表示有 3 个空闲资源(value为 3 ) ,执行这一步后,就表示剩余 2 个空闲资源 。
- 判断与阻塞 :if (S->value<0) block(S->list),在资源数量减少后,判断value值是否小于 0 。如果value小于 0 ,说明当前没有足够的空闲资源供进程使用 。此时,block(S->list)操作会将该进程阻塞,并把进程放入信号量S的等待队列list中 。例如,value初始为 1 ,有两个进程先后执行wait操作,第一个进程执行后value变为 0 ,还能获取资源;第二个进程执行后value变为 -1 ,就会被阻塞放入等待队列 。
- block方法 :作用是将调用它的进程挂起,使其从运行态进入阻塞态 。在- wait操作中,当信号量- S->value小于 0 ,意味着没有足够资源,此时调用- block(S->list),把该进程添加到信号量- S的等待队列- list里 ,让其等待资源可用 。比如餐厅没座位了,顾客就得在候座区排队等待 。
signal 操作
signal(semaphores *S) {
    S->value++;
    if (S->value<=0) wakeup(S->list);
}- 释放资源 :S->value++;表示进程释放一个单位的资源,将信号量S的value值加 1 。假设信号量value原本为 -2 (表示有 2 个进程在等待资源 ) ,执行这一步后,value变为 -1 ,代表还有 1 个进程在等待,但资源数量增加了 。
- 唤醒进程 :if (S->value<=0) wakeup(S->list);,在资源数量增加后,判断value值是否小于等于 0 。如果value小于等于 0 ,说明等待队列中还有进程在等待资源 ,wakeup(S->list)操作会从等待队列list中唤醒一个进程 ,让其有机会重新获取资源并继续执行 。比如value为 -1 时,执行此操作就会唤醒一个等待的进程 。
- wakeup方法 :功能是唤醒处于阻塞态的进程 。在- signal操作里,当信号量- S->value加 1 后小于等于 0 ,表明等待队列有进程在等资源,执行- wakeup(S->list),从等待队列中唤醒一个进程 ,让其从阻塞态变为就绪态 ,获得再次竞争 CPU 执行的机会 。就像餐厅有座位空出来,服务员从候座区叫一位顾客去就餐 。
总体而言,wait和signal操作通过对信号量 value 值的增减以及对等待队列中进程的阻塞和唤醒,实现了对资源的合理分配与管理,保障了进程间的同步与互斥 。