首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >boost中是否有允许写偏向锁定的工具?

boost中是否有允许写偏向锁定的工具?
EN

Stack Overflow用户
提问于 2012-10-10 08:04:56
回答 1查看 398关注 0票数 1

如果我有以下代码:

代码语言:javascript
运行
复制
#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做到这一点?或者我需要写我自己的?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-10-11 09:14:40

请注意,我不会评论win32实现,因为它涉及的内容更多,我没有时间详细介绍它。也就是说,它的接口与pthread实现相同,这意味着下面的答案应该是同样有效的。

从v1.51.0开始,boost::shared_mutex的pthread实现的相关部分:

代码语言:javascript
运行
复制
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锁之前获得的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12810127

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档