互斥锁的所有权不会转移到另一个线程
Ownership of mutex is not transferred to another thread
#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>
#include <csignal>
namespace
{
volatile std::sig_atomic_t gSignalStatus = 1;
}
void sig_handler(int sig){
gSignalStatus = 0;
}
boost::shared_mutex g_mutex;
using namespace std;
void reader(int id)
{
cerr<<"reader"<<id<<"started"<<endl;
while(gSignalStatus) {
boost::shared_lock<boost::shared_mutex> lock(g_mutex);
cerr << "reader"<<id << ": Got the lock" << endl;
boost::this_thread::sleep(boost::posix_time::milliseconds(200));
}
}
void writer(int id)
{
cerr<<"writer"<<id<<"started"<<endl;
while(gSignalStatus) {
boost::upgrade_lock<boost::shared_mutex> lock(g_mutex);
boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(lock);
cout <<"writer"<< id << ": Got the lock" << endl;
boost::this_thread::sleep(boost::posix_time::milliseconds(200));
}
}
int main(int argc, char* argv[])
{
std::signal(SIGINT, sig_handler);
std::vector<boost::thread*> writerthread(1);
std::vector<boost::thread*> readerthread(4);
int id = 0;
for(auto& w:writerthread) w = new boost::thread(writer, id++);
id=0;
for(auto& r:readerthread) r = new boost::thread(reader, id++);
for(auto& w:writerthread){
w->join();
delete w;
}
for(auto&r:readerthread){
r->join();
delete r;
}
return 0;
}
我实现了多阅读器/单写入器示例。
问题是,一旦写入器拥有互斥锁或读取器拥有互斥锁,则不会将其权限转移到其相反的线程(readers->writer/writer->readers(
因此,程序的输出可以是两个之一。
当作家拿到锁时
writer0started
readerwriterreader0: Got the lock
readerreader21started30started
started
started
writer0: Got the lock
writer0: Got the lock
writer0: Got the lock
writer0: Got the lock
writer0: Got the lock
当读卡器上锁时
writerreader0started
reader3startedreader
0: Got the lock
0reader2reader3: Got the lock
reader1started
reader1: Got the lock
started
started
reader2: Got the lock
reader0: Got the lock
reader3: Got the lock
reader1: Got the lock
reader2: Got the lock
reader1: Got the lock
reader2: Got the lock
reader0: Got the lock
reader3: Got the lock
readerreader3: Got the lock
reader2: Got the lock
0: Got the lock
输出与我预期的不同。
我期望的是作家和读者交替拥有锁。
这种行为是正常的吗?
是否有锁定机制的偏好?即 shared_lock
比upgrade_lock
更可取。
问题是你有紧密的循环,一旦另一个人抓住了互斥锁,读取器或写入器都无法轻易克服。看看你的循环要点:
- 锁定互斥锁
- 睡
- 释放互斥锁
- 转到步骤 1
而步骤 3 之后的窗口是读者或作者获取互斥锁的唯一机会。这个窗口很短,所以它真正抓住它的机会很小。这就是为什么您只看到编写器或仅读取器打印到控制台的原因。实际上,如果您永远等待,您很可能会看到不同的实体将有机会工作。
那么如何解决呢?这很简单:只需将睡眠从锁中移出,如下所示:
void writer(int id)
{
cerr << "writer" << id << "started" << endl;
while(gSignalStatus) {
{
boost::upgrade_lock<boost::shared_mutex> lock(g_mutex);
boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(lock);
cout << "writer" << id << ": Got the lock" << endl;
}
boost::this_thread::sleep(boost::posix_time::milliseconds(200));
}
}
void reader(int id)
{
cerr << "reader" << id << "started" << endl;
while(gSignalStatus) {
{
boost::shared_lock<boost::shared_mutex> lock(g_mutex);
cerr << "reader" << id << ": Got the lock" << endl;
}
boost::this_thread::sleep(boost::posix_time::milliseconds(200));
}
}
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 运行同一解决方案的另一个项目的项目
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- C++从另一个类访问公共静态向量的正确方法是什么
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- 使用std::transform将一个范围的元素添加到另一个范围中
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 修改函数中的指针(将另一个指针作为参数传递)
- 如何在MPI中将矩阵从一个进程转移到另一个进程
- 如果A("whole")有一组B("parts"),如何同步"part" B从A "whole"到另一个A的转移?
- 如何将所有权从一个共享指针向量转移到另一个向量?
- 是否可以将线程执行转移到另一个线程?
- 试图将静态方法从1类转移到另一个类别
- 互斥锁的所有权不会转移到另一个线程
- 根据条件将元素从一个forward_list转移到另一个
- 在C++11中,将对象的所有权从一个unique_ptr转移到另一个unique _ptr
- 可视化地将C++代码从一个程序转移到另一个程序
- 算法将一个硬币矩阵转移到另一个硬币阵列