当前位置: 首页 > 知识库问答 >
问题:

读写器的信号量解决方案:更新读写器计数和等待之间的顺序或读/写二进制信号量的信号?

公西培
2023-03-14

从操作系统概念

在第一个读写器问题的解决方案中,读写器进程共享以下数据结构:

semaphore rw mutex = 1;
semaphore mutex = 1;
int read_count = 0;

do {
wait(rw_mutex);
. . .
/* writing is performed */
. . .
signal(rw_mutex);
} while (true);

图5.11编写器进程的结构。

do {
wait(mutex);
read count++;
if (read_count == 1)
    wait(rw mutex);
signal(mutex);
. . .
/* reading is performed */
. . .
wait(mutex);
read count--;
if (read_count == 0)
    signal(rw_mutex);
signal(mutex);
} while (true);

图5.12阅读器进程的结构。

信号量互斥锁rw_mutex初始化为1;读取计数初始化为0。信号量rw_mutex对于读取和写入进程都是通用的。互斥锁信号量用于确保变量读取计数更新时的互斥。读取计数变量跟踪当前有多少进程正在读取对象。信号量rw_mutex作为编写器的互斥信号量。进入或退出临界段的第一个或最后一个读取器也使用它。当其他读者在他们的关键部分时,进入或退出的读者不使用它。

>

  • 为什么等待/信号rw_互斥体上由信号量互斥体保护
  • 在读卡器进程的结构中,我是否可以在rw\u互斥体上的上行read\u countwait/信号之间切换顺序,如下所示?

    do {
    wait(mutex);
    if (read_count == 0)
        wait(rw_mutex);
    read count++;
    signal(mutex);
    . . .
    /* reading is performed */
    . . .
    wait(mutex);
    if (read_count == 1)
        signal(rw_mutex);
    read count--;
    signal(mutex);
    } while (true);
    

    谢谢


  • 共有1个答案

    吴弘壮
    2023-03-14
    匿名用户

    1. 为什么等待/信号rw_mutex由信号量守卫互斥锁

    假设不是这样,即只有read\u count行被保护,并且您有读线程α和β。

    α增加read_count,执行信号(互斥锁),并转到执行如果(read_count==1),并且-呸!-CPU调度程序决定"足够,让其他线程也玩得开心!",并开始执行Threadβ.

    线程β锁定mutex,增加read\u count,释放mutex,并在(read\u count==1)时开始执行。现在,因为read_count是2,所以两个线程中的比较都失败了,所以没有一个读卡器使用rw_互斥锁,而您的编写器将写入正在读取的数据。

    是的,你可以。这种区别纯粹是语义上的:原文读起来是“我们将要阅读,所以增加read_count,如果我们是唯一的读者,锁定rw_mutex。进行阅读。然后,当我们完成时,减少read_count,如果我们是最后一个读者,解锁rw_mutex

    您的变体显示为“如果没有人读取,请锁定rw\u互斥锁。然后增加read\u计数。执行读取。然后,如果我们是唯一的读取器,请解锁rw\u互斥锁。减少read\u计数”。

    不过,可能出于一点兴趣,如果作者使用了您的变体,我对第一个问题的回答可能会长一点,因为另外,在带有信号(rw_mutex)代码部分,您可能会遇到死锁:∗

    此外,作者在C中描述的概念是std::shared_互斥体。

     类似资料:
    • Introduction This is the fifth part of the chapter which describes synchronization primitives in the Linux kernel and in the previous parts we finished to consider different types spinlocks, semaphore

    • 我有多个进程与Sempahore同步。我知道这段代码不允许gurantee出现这样的情况:在sem_getvalue期间,即使值变为零,甚至在调用特定进程中的sem_post之前,anotehr进程也可能调用sem_post,使值变为2。如何解决这种情况。 我的问题不能通过互斥体来解决,在我的问题中,有些进程只用于信号,即操作,而在互斥体中,所有进程都将等待并不断地发出信号

    • 在计算信号量时,没有提供相互排斥,因为有一组同时需要在临界区执行的进程。 然而,二进制信号严格提供互斥。 在这里,临界区域不能有超过1个槽位,而临界区域最多只能有1个槽位。 信号量只能有两个值,0或1。 下面,我们来看看二进制信号量的编程实现。

    • 我在做一个Qt5项目。我有一个发出clicked()信号的按钮,它的插槽中有以下代码写入串行端口: 建立到串行端口的连接后,我第一次单击按钮时,什么也没有发生。随后的单击操作正常。 我正在使用PlatformIO将Arduino代码上传到ESP32,并且在PlatformIO串行监视器中,在我第一次发出命令后立即输出,这让我认为问题是我的Qt码。 如何修复它,以便Qt可以在第一次单击按钮时读取缓冲

    • 我有: 产生项目的许多线程 要点: 生成项目比更新GUI快得多 我们可能有很多新项目同时生产 每个项目生产后都必须进行一次GUI更新 如果产品同时发生,所有产品必须只进行一次更新...没有必要多次刷新GUI 我想我正在寻找一些实现二进制信号量的标准结构,其中最大许可数是1,这样工作人员就可以调用多个,而不会相互阻塞,如果调用了一个,那么: 如果GUI线程正在睡眠= 代码应如下所示: 请注意,使用1

    • 问题内容: 我一直在尝试了解可重入锁和信号量(可重入锁的嵌套与释放/解锁机制)。 似乎拥有信号量需要您编写一个经过更彻底测试的应用程序,因为release()方法不会检查释放许可的线程是否实际上持有它。测试我的测试代码时,我发现这可能会随后使许可数量超出初始限制。另一方面,如果线程在调用unlock方法时未持有可重入锁,则将收到IllegalMonitorException。 因此,可以说没有真正