From 1859904950d95940215a748419390c3a830dcdb0 Mon Sep 17 00:00:00 2001 From: CyC2018 Date: Wed, 28 Oct 2026 22:51:26 +0800 Subject: [PATCH] =?UTF-8?q?Update=20=E8=AE=A1=E7=AE=97=E6=9C=BA=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E7=B3=BB=E7=BB=9F=20-=20=E8=BF=9B=E7=A8=8B=E7=AE=A1?= =?UTF-8?q?=E7=90=86=20-=20=E8=BF=9B=E9=98=B6.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增进阶篇,收录读者-写者问题的写者优先与公平实现。 --- notes/计算机操作系统 - 进程管理 - 进阶.md | 128 ++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 notes/计算机操作系统 - 进程管理 - 进阶.md diff --git a/notes/计算机操作系统 - 进程管理 - 进阶.md b/notes/计算机操作系统 - 进程管理 - 进阶.md new file mode 100644 index 00000000..512911ca --- /dev/null +++ b/notes/计算机操作系统 - 进程管理 - 进阶.md @@ -0,0 +1,128 @@ +# 计算机操作系统 - 进程管理 - 进阶 + +* [计算机操作系统 - 进程管理 - 进阶](#计算机操作系统---进程管理---进阶) + * [经典同步问题](#经典同步问题) + * [读者-写者问题](#读者-写者问题) + * [参考资料](#参考资料) + + + +## 经典同步问题 + +### 读者-写者问题 + +主线见[计算机操作系统 - 进程管理 · 读者-写者问题](计算机操作系统%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() { + + 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 + + +//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 +} + +//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(&resource); //reserve the resource for yourself - prevents other writers from simultaneously editing the shared resource + //writing is performed + up(&resource); //release file + + + 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 + // + down(&resourceAccess); // request exclusive access to resource + // + up(&serviceQueue); // let next in line be serviced + + // + writeResource(); // writing is performed + // + + // + up(&resourceAccess); // release resource access for next reader/writer + // +} + +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 + + // + readResource(); // reading is performed + // + + 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 +} + +``` + +## 参考资料 + +- 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)