先决条件——读者-作者问题| Set 1 (Introduction and Readers Preference Solution),进程同步中的信号量
在进程同步中,有一个非常经典的同步问题,称为读写器问题。该问题有几个子问题或变体,都涉及优先级,上面的帖子中讨论了其中一个。第二个变体的名称是Writer-priority reader-writers problem。
用于解决问题的变量集是:-
- 读者,它会跟踪一次有多少读者。
- 互斥,保护共享变量。
- Idle ,用于指示临界区中的线程数(读取器或写入器)。如果它们不是线程,那么它应该是 1,否则应该是 0。
int readers = 0 //Keeps the count of readers
idle = Semaphore (1) // 1 if no threads are present, else 0
mutex = Semaphore (1) //Mutex protects the shared counter
对于信号量变量,
wait() 的意思是“等到条件为真”和
signal()表示“条件为真的信号”
readSwitch = Lightswitch ()
writeSwitch = Lightswitch ()
noReaders = Semaphore (1)
noWriters = Semaphore (1)
首先,让我们探索当Reader 优先于 writer时的场景。
问题陈述:它指出,一旦读者准备好,读者就可以阅读文件。换句话说,如果读者有权访问对象,则没有读者应该等待,而作者则等到读者完成它。
读者优先于作者的解决方案
作家解决方案:
- Writer 请求进入临界区
- 如果允许,则它持有noReaders并写入。否则它在队列中等待,直到wait()为真
- 它退出临界区
下面是笔者的代码:
idle.wait() //Waits till the critical section is empty.
//Critical Section for the Writer
idle.signal() //Signals that the critical section is empty.
在这里,当作者处于临界区时,临界区中不存在其他线程(即读者或作者)。首先,阅读器检查临界区是否为空。如果为空,它会在那里继续并禁止作者进入。
阅读器解决方案:
- 读者请求进入临界区。
- 如果允许,则它持有noWriters,因为它持有互斥锁,任何后续读取器都在互斥锁上排队。后续读者仍可进入
- Reader 退出临界区。
这是阅读器代码:
readSwitch.lock ( noWriters ) //Locks the writer
noReaders.wait () signaling // Waits till the reader exits the critical section
//critical section for readers
noReaders.signal () //Signals that reader has exited from the Crtical section
readSwitch.unlock (noWriters) // Unlocks the reader.
问题陈述:它要求的是,一旦一个作家是准备好了,作家执行其尽快写。换句话说,如果一个作者正在等待访问该对象,则没有新的读者可以开始阅读。
Writer 优先于 Reader 时的解决方法
读者解决方案:
- 读者请求进入临界区
- 如果允许,那么,
- 它包含noWriters ,但它不包含 noReaders 。因此,如果作者到达,它可以锁定noReaders ,这将导致后续读者排队。
- 一旦最后一个读者退出,它标志着noWriters,它允许在队列中的作家进行。
这是阅读器代码:
noReaders.wait ()
readSwitch.lock ( noWriters ) // Locks the writers when readers enter the critical section
noReaders.signal () //Signals that reader is in critical section
//critical section for readers
readSwitch . unlock ( noWriters ) //Once the reader exits the critical section, then the writer is unlocked.
作家解决方案:
- Writer请求进入临界区。
- 如果允许,那么
- 它同时拥有noReaders和noWriters。这确保了临界区中没有读者和作者。
- 如果读者在临界区,它持有noWriters ,但它不持有noReaders。因此,如果作者到达它可以锁定noReaders,这将导致后续读者排队。
- 此外, writeSwitch允许多个作者在noWriters 上排队,同时锁定noReaders。因此,许多作者通过临界区甚至没有向noReaders 发出信号
- 一旦最后一个作者离开临界区,那么唯一的读者可以进入临界区
下面是笔者的代码:
writeSwitch . lock ( noReaders ) //Locks the reader
noWriters . wait () // Waits till the writer is complete.
//critical section for writers
noWriters . signal () //Signals that writer has exited from the Crtical section
writeSwitch . unlock ( noReaders ) // Unlocks the reader.
但是这种实现有一个缺点,即读者可能会饿死或可能面临长时间的延迟。为了避免饥饿,使用监视器。