我正在尝试实现以下场景。如果系统中只有读卡器,不要使用互斥锁。我已经写了下面的实现。
LockReader()
{
flag = 0;
atomic increment cntReader;
if(atomic check cntWriter > 0)
{
while(noLock != 0);
flag = 1;
mutexLock(var);
}
else
{
atomic increment noLock;
}
//CS
if(flag == 1)
mutexUnlock(var);
else
atomic decrement noLock;
atomic decrement cntReader;
}
LockWriter()
{
atomic increment cntWriter;
if(atomic check cntReader > 0)
{
while(noLock != 0);
}
mutexLock(var);
mutexUnlock(var);
atomic decrement cntWriter;
}
但这段代码的问题是,如果有一个读卡器,它在计算LockShared(
if(cntWriter > 1)
)的第3行后得到上下文切换,并且有一个writer出现,那么它就可以得到mutexLock,因为noLock还没有递增。在互斥锁之后,如果writer是上下文切换的,那么读卡器也将被允许。我们让读者和作家在一起。如何避免这种情况?
编辑1:
我把锁读取器()改成了这样:
LockReader()
{
flag = 0;
atomic increment cntReader;
atomic increment noLock;
if(atomic check cntWriter > 0)
{
atomic decrement noLock;
while(noLock != 0);
flag = 1;
mutexLock(var);
}
//CS
if(flag == 1)
mutexUnlock(var);
else
atomic decrement noLock;
atomic decrement cntReader;
}
我想这应该能解决我提到的问题。但是还有其他读写器并发问题吗?
编辑2:添加解锁代码以及。
最佳答案
如果这完全是为了性能,那么根本不应该使用互斥锁。相反,只使用一个柜台,忙着等待,即:
volatile int rw_lock;
LockReader() {
int l, success = 0;
while (success == 0) {
l = rw_lock;
if (l < 0) {
// wait for a writer
continue;
}
// atomically increment rw_lock
success == cmpset(rw_lock, l, l + 1);
}
}
LockWriter() {
int l, success = 0;
while (success == 0) {
l = rw_lock;
if (l != 0) {
// wait for readers
continue;
}
// atomically set rw_lock to -1
success = cmpset(rw_lock, 0, -1);
}
}
UnlockReader() {
atomic_dec(rw_lock);
}
UnlockWriter() {
atomic_inc(rw_lock);
}
这些类型的锁称为读写器锁。你可以在维基百科上找到更多信息:
https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock
编辑:
编写首选版本:
volatile int rw_lock;
volatile int w_req;
LockReader() {
int l, success = 0;
while (success == 0) {
while (w_req) {
// wait due to write preference
}
l = rw_lock;
if (l < 0) {
// wait for a writer
continue;
}
// atomically increment rw_lock
success == cmpset(rw_lock, l, l + 1);
}
}
LockWriter() {
int l, success = 0;
w_req = 1; // request a write, i.e. block new reads
while (success == 0) {
l = rw_lock;
if (l != 0) {
// wait for readers
continue;
}
// atomically set rw_lock to -1
success = cmpset(rw_lock, 0, -1);
}
w_req = 0; // allow new reads
}
UnlockReader() {
atomic_dec(rw_lock);
}
UnlockWriter() {
atomic_inc(rw_lock);
}
关于c - 读写器并发,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44647205/