Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;11互斥锁语义(多读/单写同步)_C++_C++11_Synchronization_C++14 - Fatal编程技术网

C++ C++;11互斥锁语义(多读/单写同步)

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{

背景-(如果您想跳过此选项)

我以前写过一些多读/单写器(multi-reader/single-writer,MRSW)实现,但它们使用的是本机或较低级别的同步机制,而不是C++11及更高版本提供的同步机制。我目前正在更新一些较旧的代码,使其更面向“现代C++”,并且更具可移植性,并研究了基于C++1x标准的解决方案。由于它的简单性和简洁性(代码复制如下,完整的线程位于),其中一个看起来特别有趣

//从上面发布的链接中,代码最初由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;}