gpt4 book ai didi

c - 读写并发

转载 作者:太空宇宙 更新时间:2023-11-04 04:22:50 25 4
gpt4 key购买 nike

我正在尝试实现以下场景。如果系统中只有读者,请不要使用互斥量。我编写了以下实现。

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 行后进行上下文切换,并且有一个作者来了,那么它可以获取 mutexLock,因为 noLock 尚未递增。在 mutexLock 之后,如果 writer 进行了上下文切换,reader 也将被允许。我们让读者和作者在一起。

如何避免这种情况?

编辑 1:我以这种方式更改了 LockReader():

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com