先决条件—读写器问题|设置1(简介和读者首选项解决方案),过程同步中的信号量
在进程同步中,有一个非常经典的同步问题,称为读写器问题。这个问题有几个子问题或变化,都涉及优先级,上面的文章中讨论了其中一个。第二种变体的名称是Writer-priority readers-writers问题。
用于解决问题的变量集为:-
- 阅读器,它跟踪一次有多少个阅读器。
- Mutex,保护共享变量。
- 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的情况。
问题陈述:它指出,一旦阅读器准备就绪,阅读器便可以阅读该文件。换句话说,如果读者可以访问该对象,则任何读者都不应等待,而作者必须等到读者完成该对象后再等待。
读者优先于作家的解决方案
作家解决方案:
- 作家要求输入关键部分
- 如果允许的话,它将保存noReaders并进行写入。否则,它在队列中等待,直到wait()为true
- 退出关键部分
这是作者代码:
idle.wait() //Waits till the critical section is empty.
//Critical Section for the Writer
idle.signal() //Signals that the critical section is empty.
在这里,当作者处于关键区域时,关键区域中没有其他线程(即读者或作家)出现。首先,阅读器检查关键部分是否为空。如果为空,它将继续在那里并禁止编写者进入。
读卡器解决方案:
- 读者要求在关键部分中输入。
- 如果允许,则它拥有noWriters。由于它拥有互斥量,因此任何后续的阅读器都在互斥量上排队。随后的读者仍然可以输入
- 读者退出关键部分。
这是读者代码:
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.
问题陈述:要求编写者准备就绪后,该编写者应尽快执行其写操作。换句话说,如果编写者正在等待访问该对象,则没有新的阅读者可以开始阅读。
作家优先于读者的解决方案
读者解决方案:
- 读者要求输入关键部分
- 如果允许的话
- 它包含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.
作家解决方案:
- 编写器要求输入关键部分。
- 如果允许的话
- 它同时拥有noReader和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.
但是这种实施方式有一个缺点,即读者可能饿死或可能面临长时间的延迟。为避免饥饿,使用了监视器。