Update 计算机操作系统 - 进程管理 - 进阶.md

新增进阶篇,收录读者-写者问题的写者优先与公平实现。
This commit is contained in:
CyC2018
2026-10-28 22:51:26 +08:00
parent dc78f94620
commit 1859904950
@@ -0,0 +1,128 @@
# 计算机操作系统 - 进程管理 - 进阶
<!-- GFM-TOC -->
* [计算机操作系统 - 进程管理 - 进阶](#计算机操作系统---进程管理---进阶)
* [经典同步问题](#经典同步问题)
* [读者-写者问题](#读者-写者问题)
* [参考资料](#参考资料)
<!-- GFM-TOC -->
## 经典同步问题
### 读者-写者问题
主线见[计算机操作系统 - 进程管理 · 读者-写者问题](计算机操作系统%20-%20进程管理.md#2-读者-写者问题),那里用 count、count_mutex 和 data_mutex 实现的是读者优先:只要还有读者在读,后到的读者可以直接进入,写者要一直等待。
以下内容由 [@Bandi Yugandhar](https://github.com/yugandharbandi) 提供。
主线中的实现可能导致写者饥饿。下面的实现是写者优先的:写者进入队列之后,只需要等待在它之前进入的读者,不会被之后到达的读者一直阻塞。
```c
int readcount, writecount; //(initial value = 0)
semaphore rmutex, wmutex, readLock, resource; //(initial value = 1)
//READER
void reader() {
<ENTRY Section>
down(&readLock); // reader is trying to enter
down(&rmutex); // lock to increase readcount
readcount++;
if (readcount == 1)
down(&resource); //if you are the first reader then lock the resource
up(&rmutex); //release for other readers
up(&readLock); //Done with trying to access the resource
<CRITICAL Section>
//reading is performed
<EXIT Section>
down(&rmutex); //reserve exit section - avoids race condition with readers
readcount--; //indicate you're leaving
if (readcount == 0) //checks if you are last reader leaving
up(&resource); //if last, you must release the locked resource
up(&rmutex); //release exit section for other readers
}
//WRITER
void writer() {
<ENTRY Section>
down(&wmutex); //reserve entry section for writers - avoids race conditions
writecount++; //report yourself as a writer entering
if (writecount == 1) //checks if you're first writer
down(&readLock); //if you're first, then you must lock the readers out. Prevent them from trying to enter CS
up(&wmutex); //release entry section
<CRITICAL Section>
down(&resource); //reserve the resource for yourself - prevents other writers from simultaneously editing the shared resource
//writing is performed
up(&resource); //release file
<EXIT Section>
down(&wmutex); //reserve exit section
writecount--; //indicate you're leaving
if (writecount == 0) //checks if you're the last writer
up(&readLock); //if you're last writer, you must unlock the readers. Allows them to try enter CS for reading
up(&wmutex); //release exit section
}
```
每个读者都必须先获取 readLock,而只有第一个写者需要获取 readLock,并且直到队列中没有写者时才会释放,因此这种实现可能导致读者饥饿。
以上两种实现总有一方可能饥饿。下面的实现使用一个先进先出的 serviceQueue 让读者和写者按到达顺序排队,获取共享数据的锁总能在有限时间内完成,因此不会出现饥饿。
```c
int readCount; // init to 0; number of readers currently accessing resource
// all semaphores initialised to 1
Semaphore resourceAccess; // controls access (read/write) to the resource
Semaphore readCountAccess; // for syncing changes to shared variable readCount
Semaphore serviceQueue; // FAIRNESS: preserves ordering of requests (signaling must be FIFO)
void writer()
{
down(&serviceQueue); // wait in line to be serviced
// <ENTER>
down(&resourceAccess); // request exclusive access to resource
// </ENTER>
up(&serviceQueue); // let next in line be serviced
// <WRITE>
writeResource(); // writing is performed
// </WRITE>
// <EXIT>
up(&resourceAccess); // release resource access for next reader/writer
// </EXIT>
}
void reader()
{
down(&serviceQueue); // wait in line to be serviced
down(&readCountAccess); // request exclusive access to readCount
// <ENTER>
if (readCount == 0) // if there are no readers already reading:
down(&resourceAccess); // request resource access for readers (writers blocked)
readCount++; // update count of active readers
// </ENTER>
up(&serviceQueue); // let next in line be serviced
up(&readCountAccess); // release access to readCount
// <READ>
readResource(); // reading is performed
// </READ>
down(&readCountAccess); // request exclusive access to readCount
// <EXIT>
readCount--; // update count of active readers
if (readCount == 0) // if there are no readers left:
up(&resourceAccess); // release resource access for all
// </EXIT>
up(&readCountAccess); // release access to readCount
}
```
## 参考资料
- Tanenbaum A S, Bos H. Modern Operating Systems [M]. Pearson, 2014.
- [Readers–writers problem - Wikipedia](https://en.wikipedia.org/wiki/Readers%E2%80%93writers_problem)