面试题答案
一键面试信号量种类及初值设定
- 互斥信号量
mutex
:用于保护共享资源(如文件相关操作),初值设为1
。 - 写信号量
writeSem
:控制写进程的互斥访问,初值设为1
,保证同一时间只有一个写进程能进行写操作。 - 读信号量
readSem
:用于协调读进程,初值设为0
,写进程完成写操作后通过这个信号量通知读进程数据更新。
各进程操作流程
- 读进程:
// 伪代码示例 while(1) { sem_wait(&mutex); // 读进程数量加一(可实现为共享变量并在临界区内操作) sem_post(&mutex); sem_wait(&readSem); // 等待写进程通知数据更新 // 执行读操作 sem_wait(&mutex); // 读进程数量减一(可实现为共享变量并在临界区内操作) sem_post(&mutex); }
- 写进程:
// 伪代码示例 while(1) { sem_wait(&writeSem); // 申请写权限 sem_wait(&mutex); // 执行写操作 sem_post(&mutex); // 通知所有读进程数据已更新 // 可以通过遍历读进程数量共享变量,多次 sem_post(&readSem),或采用广播机制 sem_post(&writeSem); }
可能出现的问题及解决方案
- 饥饿问题:写进程频繁执行可能导致读进程长时间等待。
- 解决方案:可以引入公平调度算法,如时间片轮转,对读写进程进行合理调度,确保读进程有机会执行。
- 死锁问题:如果信号量操作顺序不当,可能导致死锁。例如,读进程先获取
readSem
再获取mutex
,写进程先获取mutex
再获取writeSem
,当读进程获取readSem
后,写进程获取mutex
,此时双方都等待对方持有的信号量,就会发生死锁。- 解决方案:规定所有进程获取信号量的顺序一致,如先获取
mutex
,再获取其他信号量。
- 解决方案:规定所有进程获取信号量的顺序一致,如先获取
- 数据一致性问题:在读写操作交替频繁时,可能出现读进程读到部分更新的数据。
- 解决方案:在写进程写操作前,先设置一个标志位表示数据正在更新,读进程读取数据前先检查这个标志位,若数据正在更新则等待,直到写操作完成并清除标志位。