一、读写锁
- 允许多个进程【同时读】
- 不允许多个进程【同时写】
- 不允许多个进程【同时读写】
二、读者优先
2.1 读者执行
- 如果已经有【写者】等待,但是有【其他读者】正在读,那么【新来的读者】也可以读
2.2 写者执行
- 如果有【读者】正在读,那么【新来的写者】等待
- 如果有【其他的写者】正在写,那么【新来的写者】等待
读者写者问题,本质上是一个【互斥】问题
#include <iostream>
#include <queue>
using namespace std;
struct semaphore
{
int cnt;
queue<int> q;
};
void P(semaphore* sem)
{
sem->cnt--;
if (sem->cnt < 0)
{
// 实施P操作的进程状态会变成“阻塞态”
// 该进程会进入相应信号量的“队列末尾”
/* 重新调度其他进程 */
}
}
void V(semaphore* sem)
{
sem->cnt ++;
if (sem->cnt <= 0)
{
// cnt <= 0 说明原来的“等待队列”中有“进程”在等待资源
// 那么就“唤醒”等待队列中的一个“进程”
// 将这个进程的状态转化为“就绪态”,并将其插入“就绪队列”
}
}
semaphore rw_sem;
semaphore mtx_sem;
int rc = 0;
void reader(void)
{
while (true)
{
//--------------------------------------------------------//
P(&mtx_sem); // 保护【rc = rc + 1】
rc = rc + 1;
if (rc == 1) P(&rw_sem); // 【第一个读者】执行P操作
V(&mtx_sem);
//--------------------------------------------------------//
/* 读操作(临界区资源) */
//--------------------------------------------------------//
P(&mtx_sem); // 保护【rc = rc - 1】
rc = rc - 1;
if (rc == 0) V(&rw_sem); // 【最后一个读者】执行V操作
V(&mtx_sem);
//--------------------------------------------------------//
}
}
void writer(void)
{
while (true)
{
P(&rw_sem);
/* 写操作(临界区资源) */
V(&rw_sem);
}
}