diff --git a/notes/pics/rw-priority-timeline.png b/notes/pics/rw-priority-timeline.png
new file mode 100644
index 00000000..b42f343a
Binary files /dev/null and b/notes/pics/rw-priority-timeline.png differ
diff --git a/notes/计算机操作系统 - 进程管理 - 进阶.md b/notes/计算机操作系统 - 进程管理 - 进阶.md
index 512911ca..baf7d7de 100644
--- a/notes/计算机操作系统 - 进程管理 - 进阶.md
+++ b/notes/计算机操作系统 - 进程管理 - 进阶.md
@@ -13,56 +13,56 @@
主线见[计算机操作系统 - 进程管理 · 读者-写者问题](计算机操作系统%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)
+int readcount, writecount; // 初值都为 0
+semaphore rmutex, wmutex, readLock, resource; // 初值都为 1
-//READER
void reader() {
-
- 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
+ // 进入
+ down(&readLock); // 有写者在排队时,读者在这里被挡住
+ down(&rmutex); // 保护 readcount
+ readcount++;
+ if (readcount == 1)
+ down(&resource); // 第一个读者锁住资源,防止写者进入
+ up(&rmutex);
+ up(&readLock);
-
-//reading is performed
+ // 读
-
- 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
+ // 退出
+ down(&rmutex);
+ readcount--;
+ if (readcount == 0)
+ up(&resource); // 最后一个读者释放资源
+ up(&rmutex);
}
-//WRITER
void writer() {
-
- 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
+ // 进入
+ down(&wmutex); // 保护 writecount
+ writecount++;
+ if (writecount == 1)
+ down(&readLock); // 第一个写者挡住之后到达的读者
+ up(&wmutex);
-
- down(&resource); //reserve the resource for yourself - prevents other writers from simultaneously editing the shared resource
- //writing is performed
- up(&resource); //release file
+ down(&resource); // 写者之间互斥,并等待正在读的读者退出
+ // 写
+ up(&resource);
-
- 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
+ // 退出
+ down(&wmutex);
+ writecount--;
+ if (writecount == 0)
+ up(&readLock); // 最后一个写者放行读者
+ up(&wmutex);
}
```
@@ -71,55 +71,38 @@ void writer() {
以上两种实现总有一方可能饥饿。下面的实现使用一个先进先出的 serviceQueue 让读者和写者按到达顺序排队,获取共享数据的锁总能在有限时间内完成,因此不会出现饥饿。
```c
-int readCount; // init to 0; number of readers currently accessing resource
+int readCount; // 正在读的读者数,初值为 0
+semaphore resourceAccess; // 控制对资源的读写,初值为 1
+semaphore readCountAccess; // 保护 readCount,初值为 1
+semaphore serviceQueue; // 按到达顺序排队,初值为 1,要求按先进先出的顺序唤醒
-// 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); // 排队
+ down(&resourceAccess); // 等待独占资源
+ up(&serviceQueue); // 轮到下一个
-void writer()
-{
- down(&serviceQueue); // wait in line to be serviced
- //
- down(&resourceAccess); // request exclusive access to resource
- //
- up(&serviceQueue); // let next in line be serviced
+ writeResource(); // 写
- //
- writeResource(); // writing is performed
- //
-
- //
- up(&resourceAccess); // release resource access for next reader/writer
- //
+ up(&resourceAccess);
}
-void reader()
-{
- down(&serviceQueue); // wait in line to be serviced
- down(&readCountAccess); // request exclusive access to readCount
- //
- 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
- //
- up(&serviceQueue); // let next in line be serviced
- up(&readCountAccess); // release access to readCount
+void reader() {
+ down(&serviceQueue); // 排队
+ down(&readCountAccess);
+ if (readCount == 0)
+ down(&resourceAccess); // 第一个读者锁住资源,写者被挡住
+ readCount++;
+ up(&serviceQueue); // 轮到下一个
+ up(&readCountAccess);
- //
- readResource(); // reading is performed
- //
+ readResource(); // 读
- down(&readCountAccess); // request exclusive access to readCount
- //
- readCount--; // update count of active readers
- if (readCount == 0) // if there are no readers left:
- up(&resourceAccess); // release resource access for all
- //
- up(&readCountAccess); // release access to readCount
+ down(&readCountAccess);
+ readCount--;
+ if (readCount == 0)
+ up(&resourceAccess); // 最后一个读者释放资源
+ up(&readCountAccess);
}
-
```
## 参考资料