我有一个并发链表。我需要优先查找此列表中的查找,因此如果一个线程开始迭代列表并且后续的插入/删除请求出现,我想要排队,但如果有来自其他线程的请求,我会让这些发生。实现这种情况的最佳方法是什么?
编辑:我不想复制清单。太贵了。妈妈支付我的硬件费用。答案 0 :(得分:5)
听起来你正在寻找readers-/writer-lock。这是一个锁,可用于让许多线程读取数据结构,但是当一个线程具有写访问权限时,所有其他线程都被锁定。
Boost提供implementation。
答案 1 :(得分:0)
你在Windows上吗? 如果是这样,您可以使用诸如Events或Mutexes之类的同步对象。
对于插入和删除,您可以在这些函数的开头锁定互斥锁,并在函数末尾释放互斥锁。
步骤如下所示。
创建事件对象。 http://msdn.microsoft.com/en-us/library/ms682655(VS.85).aspx
在插入/删除功能开始时使用WaitForSingleObject函数锁定Event对象。 http://msdn.microsoft.com/en-us/library/ms687032(VS.85).aspx
使用SetEvent在插入/删除功能结束时解锁事件对象,以便等待此事件对象的线程将轮到执行插入/删除。 http://msdn.microsoft.com/en-us/library/ms686211(VS.85).aspx
读取不需要获取锁定。所以不需要Event或Mutex来阅读。多个线程可以从共享缓冲区同时读取。
您可以在以下位置找到关于Reader-writer锁定的一般信息 http://en.wikipedia.org/wiki/Readers-writer_lock
你可以获得示例程序 http://msdn.microsoft.com/en-us/library/ms686915(v=VS.85).aspx
答案 2 :(得分:0)
听起来像香草读写器锁不是你想要的。一旦你试图获得锁定的写入端,进一步的读者将阻塞直到编写器完成,而你说你想要额外的线程进行读取以获得访问,即使有插入挂起。
我不确定你想要的是否安全。如果有足够的读取,则插入/删除可能会永久阻塞。
如果你真的想要这个,你可以轻松自己构建它,就像你可以轻松地在标准互斥锁之上构建一个读/写锁。
请注意,此代码可能已损坏,但可能会为您提供一般概念。
class UnfairReaderWriterMutex {
Mutex mutex;
CondVar condition;
int readers; // if positive, reader count; if -1, writer lock is held
public:
UnfairReaderWriterMutex() : counter(0) { }
void ReaderLock() {
mutex.Lock();
while (counter < 0) {
condition.Wait();
}
++readers;
mutex.Unlock();
}
void ReaderUnlock() {
mutex.Lock();
assert(readers > 0);
--readers;
condition.Notify(); // only need to wake up one writer
mutex.Unlock();
}
void WriterLock() {
mutex.Lock();
while (counter > 0) {
condition.Wait();
}
readers = -1;
mutex.Unlock();
}
void WriterUnlock() {
mutex.Lock();
assert(readers == -1);
readers = 0;
condition.NotifyAll(); // there may be multiple readers waiting
mutex.Unlock();
}
};
典型的读/写锁就像这样工作,只是有一个标志阻止读者在作家等待时获取锁。