mirror of
https://github.com/CyC2018/Interview-Notebook.git
synced 2026-11-01 11:43:46 +00:00
Update 计算机操作系统 - 进程管理 - 进阶.md
补充读者-写者问题三种实现的时序对比配图,更新写优先与公平排队代码的中文注释与格式。
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 208 KiB |
@@ -13,56 +13,56 @@
|
||||
|
||||
主线见[计算机操作系统 - 进程管理 · 读者-写者问题](计算机操作系统%20-%20进程管理.md#2-读者-写者问题),那里用 count、count_mutex 和 data_mutex 实现的是读者优先:只要还有读者在读,后到的读者可以直接进入,写者要一直等待。
|
||||
|
||||
三种实现的差别可以用同一组到达顺序来比较(按主线和本节的代码逐行模拟,信号量按先进先出的顺序唤醒):
|
||||
|
||||
<div align="center"> <img src="pics/rw-priority-timeline.png" width="760px"/> </div><br>
|
||||
|
||||
以下内容由 [@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() {
|
||||
<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
|
||||
// 进入
|
||||
down(&readLock); // 有写者在排队时,读者在这里被挡住
|
||||
down(&rmutex); // 保护 readcount
|
||||
readcount++;
|
||||
if (readcount == 1)
|
||||
down(&resource); // 第一个读者锁住资源,防止写者进入
|
||||
up(&rmutex);
|
||||
up(&readLock);
|
||||
|
||||
<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
|
||||
// 退出
|
||||
down(&rmutex);
|
||||
readcount--;
|
||||
if (readcount == 0)
|
||||
up(&resource); // 最后一个读者释放资源
|
||||
up(&rmutex);
|
||||
}
|
||||
|
||||
//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
|
||||
// 进入
|
||||
down(&wmutex); // 保护 writecount
|
||||
writecount++;
|
||||
if (writecount == 1)
|
||||
down(&readLock); // 第一个写者挡住之后到达的读者
|
||||
up(&wmutex);
|
||||
|
||||
<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
|
||||
down(&resource); // 写者之间互斥,并等待正在读的读者退出
|
||||
// 写
|
||||
up(&resource);
|
||||
|
||||
<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
|
||||
// 退出
|
||||
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
|
||||
// <ENTER>
|
||||
down(&resourceAccess); // request exclusive access to resource
|
||||
// </ENTER>
|
||||
up(&serviceQueue); // let next in line be serviced
|
||||
writeResource(); // 写
|
||||
|
||||
// <WRITE>
|
||||
writeResource(); // writing is performed
|
||||
// </WRITE>
|
||||
|
||||
// <EXIT>
|
||||
up(&resourceAccess); // release resource access for next reader/writer
|
||||
// </EXIT>
|
||||
up(&resourceAccess);
|
||||
}
|
||||
|
||||
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
|
||||
void reader() {
|
||||
down(&serviceQueue); // 排队
|
||||
down(&readCountAccess);
|
||||
if (readCount == 0)
|
||||
down(&resourceAccess); // 第一个读者锁住资源,写者被挡住
|
||||
readCount++;
|
||||
up(&serviceQueue); // 轮到下一个
|
||||
up(&readCountAccess);
|
||||
|
||||
// <READ>
|
||||
readResource(); // reading is performed
|
||||
// </READ>
|
||||
readResource(); // 读
|
||||
|
||||
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
|
||||
down(&readCountAccess);
|
||||
readCount--;
|
||||
if (readCount == 0)
|
||||
up(&resourceAccess); // 最后一个读者释放资源
|
||||
up(&readCountAccess);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 参考资料
|
||||
|
||||
Reference in New Issue
Block a user