我正在尝试实现以下场景。如果系统中只有读卡器,不要使用互斥锁。我已经写了下面的实现。

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/

10-11 18:54