Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Boost:互斥锁可以从任何线程解锁吗?_Multithreading_Boost_Mutex - Fatal编程技术网

Multithreading Boost:互斥锁可以从任何线程解锁吗?

Multithreading Boost:互斥锁可以从任何线程解锁吗?,multithreading,boost,mutex,Multithreading,Boost,Mutex,我最近开始使用boost::thread WinXP、VS10和BoostPro,发现互斥锁可以由任何线程解锁,而不仅仅是由拥有它的线程解锁。 此外,基本的lock_guard+mutex组合对多重锁定和解锁进行了一些内部计数,但我想这不是一个大问题 有人知道为什么它是这样设计的吗?是故意的吗? 或者我的构建环境/libs可能有问题 示例应用程序: #include <iostream> #include <boost/thread.hpp> using namespa

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

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

示例应用程序:

#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;
}

谢谢,

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


win32实现似乎使用原子指令实现了互斥体的大部分逻辑——可能这是因为win32上对更复杂的互斥体类型递归/定时的支持有限。Win32的本机关键部分只能用于简单的互斥体,而Win32的本机互斥体对于进程内互斥体来说太重了。

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


win32实现似乎使用原子指令实现了互斥体的大部分逻辑——可能这是因为win32上对更复杂的互斥体类型递归/定时的支持有限。Win32的本机关键部分只能用于简单的互斥体,而Win32的本机互斥体对于进程内互斥体来说太重了。

所以我想我的开发环境还可以。我非常清楚boost文档中的内容,但我相信这种行为会导致在大型应用程序中出现非常严重且难以检测的错误。文档语句本身不能防止编程错误。在我看来,正如您所指出的,调试构建中至少应该有一些断言,文档中也应该有关于这种情况下未定义行为的信息。再次感谢您的评论。@Oedo808,以及您对Win32实现的评论。我相信1 7 boost正在使用Lamport的面包房。所以我想我的开发环境还可以。我非常清楚boost文档中的内容,但我相信这种行为会导致在大型应用程序中出现非常严重且难以检测的错误。文档语句本身不能防止编程错误。在我看来,正如您所指出的,调试构建中至少应该有一些断言,文档中也应该有关于这种情况下未定义行为的信息。再次感谢您的评论。@Oedo808,以及您对Win32实现的评论。我相信155Boost正在使用兰波特的面包店。