Readers-Writer Problem 扩展版本,Readers 遍历整个文件

Readers-Writer Problem Extended Version, Readers traverse the whole file

提问人:Kenny Ynnek 提问时间:4/7/2023 最后编辑:Kenny Ynnek 更新时间:4/7/2023 访问量:117

问:

背景

我目前正在学习操作系统课程,讲座向我们介绍了多读写器问题:

作家:

do {
            wait (wrt) ;
            // writing is performed
            signal (wrt) ;
} while (true)

读者:

do  {
    wait (mutex);
    readcount ++;
    if (readcount == 1)  wait (wrt);
    signal (mutex)
    // reading is performed
    wait (mutex);
    readcount--;
    if (readcount  == 0)  signal (wrt) ;
    signal (mutex) ;
} while (true)
  • 如果一个写入器在 CS 中,并且 n 个读取器正在等待,则一个读取器在 上排队,而 n-1 个读取器在 上排队。wrtmutex
  • 当一个写入器执行时,将恢复执行,调度程序选择要执行的执行。signal(wrt)

描述:

我知道有很多关于读者和作家问题的资源。但我只是想到了一个有趣的场景,如果,读者真的习惯于遍历作者写的文字呢?

更具挑战性的扩展版本:

1 个作家不断将内容写入文本文件

n 个读者阅读整个文件,但每次只阅读作者当前编写的文本。

对于 n 个读取器,每个读取每次只读取文本文件的一部分,例如: 对于包含以下内容的文本文件:

[Part A][Part B]...[Part N]

第一个读者只读,然后下一个读者读,依此类推,直到整个文本文件被所有子级读完,然后父级会清除文本文件中已有的东西,并在上面再次写一些东西,写完后,读者线程可以继续阅读,一遍又一遍[part A][part B]

问题:

是否可以仅使用互斥锁来实现,如上所述?如果没有,我该如何实现?wrtmutex

到目前为止,我的想法:

我们可能需要定义一个缓冲区大小和一个 char 指针来跟踪所有线程读取了多少文本文件。假设我们可以使用条件变量,但同步仍然是一个问题。

如果您觉得我的描述令人困惑,我深表歉意。我会尽量清楚地表达出来。我也欢迎任何想法,任何建议,(伪)代码实现更好,但不是必须的。

C 多线程 算法 操作系统 同步

评论


答:

0赞 chinmay rajpurohit 4/7/2023 #1

我认为您是在问读者可以从数据库中读取不同的数据,但是在 IPC 的读取器编写器问题中,多个读取器可以读取并输入 CS,读取器可以不同,所以最终如果这里有 2 个读取器想要读取 A 部分,他们会阅读。决定读者将阅读什么有什么意义。如果我误解了你的问题,请纠正我。

评论

0赞 Kenny Ynnek 4/7/2023
我真正想做的是使用多个读取器线程来遍历整个文件。“独特”可能是一个糟糕的词选择,对于造成的任何混淆,深表歉意。
0赞 chinmay rajpurohit 4/7/2023
所以你必须改变代码本身,我认为我们不能通过使用信号量来实现这一点。我们必须对数据库文件/相应的记录使用可能的锁定协议。
0赞 Kenny Ynnek 4/7/2023
嗯,如果我们可以使用条件变量呢?这会改变什么吗?
0赞 Kenny Ynnek 4/7/2023 #2

这是我建议的伪代码解决方案:

full = 0, empty = 0, mutex = 1, read_mutex = 1
-------------------------------

作家:

while read_count < file_count:
    //writer stuff -> buffer, num_read
    post(full)
    wait(empty)

READER_THREADS


while(read_count < file_count):
    wait(mutex)
    readerCount++;
    if(readerCount == 1): wait(full)
    wait(read_mutex)
    while already_read < num_read:
        //read the small buffer
        //update already_read
        post(read_mutex)
        post(mutex)
    readerCount--
    if(readerCount  == 0) : post(empty)
    post(mutex)```