我目前正在学习大学的并发性。在这种情况下,我必须在C中实现读者/作者问题,我认为我在正确的轨道上。
我对这个问题的看法是,我们需要两个锁{
name: 'Chrome',
y: 61.41,
sliced: true,
color: 'rgba(255, 255, 255, 0.61)',
}
和rd_lock
。当编写器线程想要更改我们的全局变量时,它会尝试获取两个锁,写入全局变量并解锁。当读者想要读取全局时,它会检查wr_lock
当前是否被锁定,然后读取该值,但是其中一个读者线程应该抓住wr_lock
,但其他读者不应该关心rd_lock
已被锁定。
我不允许使用pthread库中已有的实现。
rd_lock
目前,当使用1个阅读器和1个编写器运行时,它只打印了很多零,这意味着它从未实际执行编写器线程中的代码。我知道这对于多个读者来说并不像预期的那样有效,但是当我用其中一个读者运行它时,我不明白什么是错的。
答案 0 :(得分:1)
不要将锁视为“读取器锁定”和“写入器锁定”。
因为您需要允许多个并发读取器,所以读者无法持有互斥锁。 (如果它们这样做,它们被序列化;只有一个可以同时持有互斥锁。)它们可以在短时间内(在它们开始访问之前,在它们结束访问之后)获取一个,以更新状态,但那是它
将rwlock分为三个部分的时间线:“抓住rwlock”,“do work”,“release rwlock”。
例如,您可以使用一个互斥锁,一个条件变量和一个计数器。该计数器包含活跃读者的数量。条件变量由最后一个读取器和作者在释放互斥锁之前发出信号,以唤醒等待的写入器。互斥锁保护两者,并在写操作的整个持续时间内由写入器保持。
所以,在伪代码中,你可能有
Function rwlock_rdlock:
Take mutex
Increment counter
Release mutex
End Function
Function rwlock_rdunlock:
Take mutex
Decrement counter
If counter == 0, Then:
Signal_on cond
End If
Release mutex
End Function
Function rwlock_wrlock:
Take mutex
While counter > 0:
Wait_on cond
End Function
Function rwlock_unlock:
Signal_on cond
Release mutex
End Function
请记住,无论何时等待条件变量,互斥锁都会在等待期间原子释放,并在线程唤醒时自动获取。因此,对于等待条件变量,线程将在等待之前和之后都具有互斥锁,但不会在等待本身期间。
现在,上述方法并不是您可能实施的唯一方法。
特别是,您可能会注意到在上面的方案中,您必须使用不同的“解锁”操作,具体取决于您是否对rwlock进行了读取或写入锁定。在POSIX pthread_rwlock_t
实施中,只有一个pthread_rwlock_unlock()
。
无论你设计什么样的方案,重要的是要检查它是否适用于所有情况:一个独立的读取锁定器,一个单独的写入锁定器,几个读取锁定器,多个写入锁定器,一个单独的写入 - 储物柜和一个读锁柜,一个独立的写锁柜和几个读锁柜,几个写锁柜和一个独立的读锁柜,以及几个读写锁柜。
例如,让我们考虑有多个活动读者的情况,并且编写者想要写锁定rwlock。
作家抓住互斥锁。然后它注意到计数器非零,因此它开始等待条件变量。当最后一个读者 - 注意读者退出的顺序无关紧要,因为使用了一个简单的计数器! - 解锁rwlock上的读锁,它在条件变量上发出信号,唤醒编写器。然后作者抓住互斥锁,看到计数器为零,然后开始工作。在此期间,互斥锁由作者保存,因此所有新读者都将阻止,直到作者释放互斥锁。因为作者在释放互斥锁时也会在条件变量上发出信号,这是其他等待的作者和等待的读者之间的竞争,他们会接下来。