c++ - 锁定已在其他线程中锁定的 boost::unique_lock 时抛出异常

标签 c++ multithreading boost

有全局对象boost::unique_lock。一个线程锁定它。当其他线程试图锁定异常“已经拥有互斥锁”时抛出。为什么会这样?我希望线程被阻塞,直到其他线程调用解锁。

boost::mutex mutex;
boost::unique_lock<boost::mutex> lock(mutex);

static void* scheduller(void* arg)
{
    boost::this_thread::sleep(boost::posix_time::seconds(5));
    lock.lock();    
    return 0;
}

static void* usb(void* arg)
{
    lock.lock();
    boost::this_thread::sleep(boost::posix_time::seconds(20));
    return 0;
}

int BEvent_test()
{
    lock.unlock();
    int a = 0;
    boost::thread thread1(usb,&a);
    boost::thread thread2(scheduller,&a);
    boost::this_thread::sleep(boost::posix_time::seconds(100));
    return 0;

}

在 BEvent_test 函数中,我正在解锁,因为唯一锁在构造函数中被锁定。延迟确保调度程序线程在 usb 线程之后启动。当它尝试执行 lock() 异常时抛出。为什么?

最佳答案

您对 unique_lock 的使用是错误的,特别是那些对象应该在不同线程之间共享,因为它们不是线程安全的。是的,这乍一听起来很奇怪,但它确实有道理,因为线程安全和提供线程安全是两个截然不同的事情。

unique_lock 的想法是帮助您管理 互斥锁。为此,您只在本地 创建这些对象。这也是它最初被锁定的原因,您似乎可以通过解锁来“解决”这个问题。但是,您应该尝试使用它们的作用域/生命周期来管理锁。

现在,您说您需要一个 unique_lock 才能使用事件。是和不是。对于使用该事件的每个线程,您都需要一个,但不是完全相同的一个。相反,您可以使用来自不同线程的不同本地锁实例。顺便说一句:事件需要锁的原因是在等待事件时,必须释放锁。在收到事件(或超时)后,它也必须重新获取锁。换句话说,锁充当互斥锁的代理,提供间接和一些额外的保证。

您收到异常的原因是您尝试锁定 unique_lock 两次。我认为这是来自同一个线程并不重要,我什至不会说它真的来自同一个线程。但是,当您锁定互斥量(通过 unique_lock)时,您说您现在正在进入临界区。这意味着之前,您不在那个关键部分。如果 unique_lock 现在发现锁已经持有,这意味着您的代码中出现了错误,因为代码似乎混淆了它是否在临界区内。出于这个原因,您会得到一个异常作为修复代码的动力。

关于c++ - 锁定已在其他线程中锁定的 boost::unique_lock 时抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30600645/

相关文章:

c++ - 段错误澄清

c++ - 迭代器和 const_iterator operator++ post and prefix

c++ - 字段 'buffer_' 的类型不完整 'boost::array<char , 4096ul>'

c++ - 如何使用boost在C++中获取带有尾随路径分隔符的路径

c++ - abort() 的调用者在回溯中是未知的,任何调试它的建议

c++ - 如何获取文件夹的 ACL

c++ - 将 OpenMP 应用于 C++ 中的特定嵌套循环

c++ - c++多线程应用程序上的内存损坏

Java 互锁线程

c++ - NLP项目,python或C++