C++ C++;11互斥锁语义(多读/单写同步)
背景-(如果您想跳过此选项) 我以前写过一些多读/单写器(multi-reader/single-writer,MRSW)实现,但它们使用的是本机或较低级别的同步机制,而不是C++11及更高版本提供的同步机制。我目前正在更新一些较旧的代码,使其更面向“现代C++”,并且更具可移植性,并研究了基于C++1x标准的解决方案。由于它的简单性和简洁性(代码复制如下,完整的线程位于),其中一个看起来特别有趣C++ C++;11互斥锁语义(多读/单写同步),c++,c++11,synchronization,c++14,C++,C++11,Synchronization,C++14,背景-(如果您想跳过此选项) 我以前写过一些多读/单写器(multi-reader/single-writer,MRSW)实现,但它们使用的是本机或较低级别的同步机制,而不是C++11及更高版本提供的同步机制。我目前正在更新一些较旧的代码,使其更面向“现代C++”,并且更具可移植性,并研究了基于C++1x标准的解决方案。由于它的简单性和简洁性(代码复制如下,完整的线程位于),其中一个看起来特别有趣 //从上面发布的链接中,代码最初由qqibrow编写,由sbi在堆栈溢出时编辑 类RWLock{
//从上面发布的链接中,代码最初由qqibrow编写,由sbi在堆栈溢出时编辑
类RWLock{
公众:
RWLock()
:shared()
,readerQ(),writerQ()
、活动\u读卡器(0)、等待\u写卡器(0)、活动\u写卡器(0)
{}
void ReadLock(){
std::唯一锁定lk(共享);
while(waiting_writers!=0)//下面的问题
readerQ.wait(lk);
++积极的读者;
lk.unlock();
}
void ReadUnlock(){
std::唯一锁定lk(共享);
--积极的读者;
lk.unlock();
writerQ.notify_one();
}
void WriteLock(){
std::唯一锁定lk(共享);
++等待的作家;
while(active|u readers!=0 | active|u writers!=0)//下面的问题
writerQ.wait(lk);
++活跃的作家;
lk.unlock();
}
void WriteUnlock(){
std::唯一锁定lk(共享);
--等待的作家;
--活跃的作家;
如果(等待写入程序>0)
writerQ.notify_one();
其他的
readerQ.notify_all();
lk.unlock();
}
私人:
std::互斥共享;
std::条件变量读取器Q;
std::条件_变量写入器q;
int主动读卡器;
国际作家协会;
国际活跃作家;
};
我的问题
我的问题是关于这个MRSW实现的互斥锁和访问的语义,特别是std::unique_lock
(特别是上面代码中注释中标记的行)。使用传统的低级同步,在ReadLock()
或WriteLock()
获得对同步对象的独占所有权后,在获得锁的同时,另一个线程如何修改等待的写入程序
、活动的读取程序
或活动的写入程序
?正如我所提到的,我以前在MRSW中使用过两门方法,但是上述实现的简单性让我觉得它要么太简单而不正确,要么我缺少了C++1x中独占锁定的语义
我已经看过相关的参考文献,但是像这样的案例的语义不是特别清楚(例如)
似乎解锁需要以不同的方式处理,我可能遗漏了一些东西,但我真的希望它是什么
谢谢 为什么
active\u readers
,active\u writers
,不是原子的?如果您已经在使用C++11,那么std::shared\u mutex
有什么问题?@user9335240-如果您使用mutex锁定整个对象,它们不需要是原子的,但我的问题是,如果对象被锁定,如何访问它们?这是关于unique\u lock
的语义std::condition\u variable
在等待时解锁互斥锁,在唤醒时重新锁定。-这就是为什么需要std::unique_lock
@frasnian:还要注意,您可以将谓词与wait()
一起使用,以避免使用手动循环。您不必显式地解锁
互斥锁,当它超出范围时,它将解锁void ReadLock(){std::unique_lock lk(共享);readerQ.wait(lk,[&](){return waiting_writers==0;});++active_readers;}
void WriteLock(){std::unique_lock lk(共享);++waiting_writers;writerQ.wait(lk,[&](){return active_readers==0&&active_writers==0});++active writers;}