boost中是否有允许写偏锁定的功能

Is there a facility in boost to allow for write-biased locking?

本文关键字:锁定 功能 许写偏 是否 boost      更新时间:2023-10-16

如果我有以下代码:

#include <boost/date_time.hpp>
#include <boost/thread.hpp>
boost::shared_mutex g_sharedMutex;
void reader()
{
boost::shared_lock<boost::shared_mutex> lock(g_sharedMutex);
boost::this_thread::sleep(boost::posix_time::seconds(10));
}
void makeReaders()
{
while (1)
{
boost::thread ar(reader);
boost::this_thread::sleep(boost::posix_time::seconds(3));
}
}
boost::thread mr(makeReaders);
boost::this_thread::sleep(boost::posix_time::seconds(5));
boost::unique_lock<boost::shared_mutex> lock(g_sharedMutex);
...

唯一的锁永远不会被获取,因为总会有读者。我想要一个unique_lock,当它开始等待时,它可以防止任何新的读锁访问互斥锁(根据我的wiki搜索,称为写偏锁或写首选锁)。有没有一种简单的方法可以通过boost实现这一点?还是我需要自己写?

请注意,我不会对win32实现发表评论,因为它涉及的内容要多得多,而且我没有时间详细介绍它。话虽如此,它的接口与pthread实现相同,这意味着以下答案应该同样有效。

自v1.5.0:起,boost::shared_mutex的pthread实现的相关部分

void lock_shared()
{
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
while(state.exclusive || state.exclusive_waiting_blocked)
{
shared_cond.wait(lk);
}
++state.shared_count;
}
void lock()
{
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
while(state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=true;
exclusive_cond.wait(lk);
}
state.exclusive=true;
}

while循环条件对您来说是最相关的部分。对于lock_shared函数(读锁),请注意,只要有线程试图获取(state.exclusive_waiting_blocked)或已经拥有(state.exclusive)锁,while循环就不会终止。这本质上意味着写锁的优先级高于读锁。

对于锁函数(写锁),只要至少有一个线程当前拥有读锁(state.shared_count)或另一个线程拥有写锁(state.exclusive),while循环就不会终止。这基本上为您提供了通常的互斥保证。

至于死锁,读锁总是会返回,只要写锁在获取后能够保证解锁。至于写锁,只要读锁和写锁总是保证在获取后解锁,就保证会返回。

如果您想知道,state_change互斥锁用于确保不会同时调用这两个函数。我不打算讨论解锁功能,因为它们有点复杂。请随意查看它们,毕竟您有来源(boost/thread/pthread/shared_mutex.hpp):)

总而言之,这几乎是一个文本书实现,它们已经在广泛的场景中进行了广泛的测试(libs/thread/test/test_shared_mutex.cpp和整个行业的大规模使用)。我不会太担心,只要你习惯地使用它们(没有递归锁定,总是使用RAII助手进行锁定)。如果您仍然不信任实现,那么您可以编写一个随机测试,模拟您担心的任何测试用例,并让它在数百个线程上运行一夜。这通常是解决死锁的好方法。

现在,为什么您会看到在请求写锁之后会获取读锁?如果没有看到您正在使用的诊断代码,很难说。读锁很可能是在打印语句(或您正在使用的任何语句)完成之后,在写线程中获取state_change锁之前获取的。