【问题标题】:Boost: mutex unlocking from any thread possible?Boost:可以从任何线程解锁互斥锁?
【发布时间】:2011-09-10 12:44:50
【问题描述】:

我最近开始使用 boost::thread(WinXP、VS10、BoostPro),发现互斥锁可以被任何线程解锁,而不仅仅是拥有它的线程。 此外,基本的 lock_guard + mutex 组合似乎正在对多个 lock() 和 unlock() 进行一些内部计数,但我猜这不是一个大问题。

有人知道为什么会这样设计吗?是故意的吗? (或者我的构建环境/库可能有问题?)

示例应用:

#include <iostream>
#include <boost/thread.hpp>

using namespace std;


class NamedThread
{
public:
    NamedThread(string name_, boost::mutex& mtx_) :
      mtx(mtx_), name(name_) {}

    void operator ()()
    {
        for (int i = 0; i < 10; ++i)
        {
            boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
            cout << name << endl;

            //boost::lock_guard<boost::mutex> guard1(mtx);
            //boost::lock_guard<boost::mutex> guard2(mtx);

            boost::unique_lock<boost::mutex> guard1(mtx);
            boost::unique_lock<boost::mutex> guard2(mtx);
        }


    }

    string name;
    boost::mutex& mtx;
};

class UnlockerThread
{
public:
    UnlockerThread(string name_, boost::mutex& mtx_) :
      mtx(mtx_), name(name_) {}

    void operator ()()
    {
        for (int i = 0; i < 100; ++i)
        {
            boost::this_thread::sleep(boost::posix_time::milliseconds(3000));
            cout << name << ": unlocking" << endl;
            mtx.unlock(); // !!! IT WORKS !!!
        }
    }

    string name;
    boost::mutex& mtx;
};


int main()
{
    boost::mutex mtx;

    NamedThread th2("Thread1", mtx);
    boost::thread t2(th2);

    UnlockerThread th3("UnlockerThread", mtx);
    boost::thread t3(th3);

    t2.join();

    char ch;
    cin >> ch;
    return 0;
}

谢谢,

【问题讨论】:

    标签: multithreading boost mutex


    【解决方案1】:

    boost 文档非常清楚,调用 mutex.unlock 的前提条件是“当前线程拥有 *this”。这并不意味着违反该先决条件会导致异常/错误/崩溃(尽管这对于调试构建可能很好),但在这种情况下您不能依赖任何特定行为。

    win32 实现似乎使用原子指令实现了互斥锁的大部分逻辑 - 这可能是因为在 win32 上对更复杂的互斥锁类型(递归/定时)的支持有限。 Win32 的原生临界区只能用于简单的互斥体(而且 Win32 的原生互斥体对于进程内互斥体来说太重了)。

    【讨论】:

    • 所以我想我的开发环境还可以。我完全了解 boost 文档中的内容,但我相信这种行为会导致大型应用程序中出现非常严重且难以检测的错误。单靠文档声明不能防止编程错误。在我看来,正如您所指出的,在调试版本中至少应该有一些断言,以及在这种情况下,文档中应该有关于未定义行为的信息。再次感谢您的 cmets。
    • @Oedo808 除了您对 Win32 实施的评论。我相信 1_55 的提升是使用 Lamport 的面包店 (en.wikipedia.org/wiki/Lamport's_bakery_algorithm)。
    猜你喜欢
    • 2012-12-25
    • 2011-02-14
    • 2018-05-23
    • 1970-01-01
    • 2013-01-31
    • 2010-11-18
    • 2022-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多