我有一个多线程应用程序,必须经常读取一些数据,偶尔会更新数据。我通过使用unique_lock和使用upgrade_lock进行读取时出现问题 有我的问题的例子:
void unlock(){
test.stream = 0;
test.mtx.unlock();
}
void lock_mtx(int i){
boost::unique_lock<boost::shared_mutex> lock(test.mtx);
test.stream = i;
boost::this_thread::sleep_for(boost::chrono::milliseconds(10000));
unlock();
boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
}
当我破坏lock
时,此线程已经解锁了互斥锁,有时它被另一个线程锁定,但是析构函数再次释放它。破坏锁定后(在第一个线程中)第三个线程占用互斥锁,我在一个时刻有两个编写器
void lock_mtx(int i){
boost::upgrade_lock<boost::shared_mutex> lock(test.mtx);
read_from_locked();
boost::this_thread::sleep_for(boost::chrono::milliseconds(5000));
boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock);
write_to_locked();
boost::this_thread::sleep_for(boost::chrono::milliseconds(10000));
}
第二个问题是,当某个线程占用upgrade_lock
时,其他线程无法读取共享对象
MS VisualStudio 2013和Windows8 x64中都出现了这两个问题
答案 0 :(得分:1)
void lock_mtx(int i)
{
{
boost::unique_lock<boost::shared_mutex> lock(test.mtx);
test.stream = i;
boost::this_thread::sleep_for(boost::chrono::milliseconds(10000));
}
boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
}
unique_lock
和lock_guard
的目的是在超出范围时自动解锁互斥锁。这种模式称为RAII。
经验法则:切勿在(基本|共享)可锁定对象上手动调用lock()
/ unlock()
。这是反模式,因为
lock_guard
或unique_lock
)成为包含类的成员,或者返回unique_lock
以便调用者可以选择明确地 adopt
锁定,或者让它自动由警卫释放。