天天看点

boost互斥锁_Boost:可能从任何线程解锁互斥锁吗?

boost互斥锁_Boost:可能从任何线程解锁互斥锁吗?

I started using boost::thread recently (WinXP, VS10, BoostPro) and found that mutex can be unlocked by any thread, not by the thread that owns it only.

Additionally it seams that the basic lock_guard + mutex combo is doing some internal counting of multiple lock() and unlock() but it is not a big issue I guess.

Does somebody know why it was designed in such a way? Is it on purpose?

(or maybe there is something wrong with my build environment / libs?)

Example app:

#include

#include

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<:mutex> guard1(mtx);

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

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

boost::unique_lock<: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;

}

Thanks,

解决方案

The boost documentation is very clear that a precondition for calling mutex.unlock is that "the current thread owns *this." That doesn't mean that violating that precondition will result in an exception/error/crash (although it might be nice for a debug build), but you can't rely on any specific behaviour in that case.

The win32 implementation appears to implement most of the logic for a mutex using atomic instructions - presumably this is because of limited support for more complex mutex types (recursive/timed) on win32. Win32's native critical sections can only be used for simple mutexes (and Win32's native mutexes are too heavyweight for in-process mutexes).