2011-09-10 10 views
0

私は最近boost :: thread(WinXP、VS10、BoostPro)を使い始めましたが、それを所有するスレッドではなく、どのスレッドでもmutexをロック解除できることがわかりました。 さらに、基本的なlock_guard + mutexのコンボが複数のlock()とunlock()の内部カウントを行っているという点は縫い合わせていますが、それは大きな問題ではありません。ブースト:任意のスレッドからの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; 
} 

おかげで、

答えて

2

ブーストドキュメントは非常に明確であることmutex.unlockを呼び出すための前提条件「現在のスレッドが* thisを所有している」ということです。これは、その前提条件に違反すると例外/エラー/クラッシュが発生することを意味するわけではありませんが(デバッグビルドには良いかもしれませんが)、その場合の特定の動作に依存することはできません。

win32の実装では、アトミック命令を使用してミューテックスのロジックのほとんどを実装しているようです。おそらく、これはWin32でより複雑なミューテックスタイプ(再帰的/時間的)をサポートしていないためです。 Win32のネイティブクリティカルセクションは、単純なミューテックスにしか使用できません(また、Win32のネイティブミューテックスは、インプロセスミューテックスでは重すぎます)。

+0

私は私の開発環境はOKだと思います。私は完全に何がブーストのドキュメントにあるか知っていますが、私はこの種の振る舞いが大規模なアプリケーションでは非常に深刻で難しいエラーを検出する可能性があると信じています。ドキュメンテーション文だけではプログラミングエラーを防ぐことはできません。私の意見では、あなたが指摘したようにデバッグビルドには少なくともいくつかのアサーションが存在し、そのような場合には未定義の動作についてのドキュメントの情報が必要です。あなたのコメントをありがとう。 – Oedo808

+1

@ Oedo808 Win32の実装に関するあなたのコメントに加えて。私は1_55でLamportのベーカリー(http://en.wikipedia.org/wiki/Lamport's_bakery_algorithm)を使っていると信じています。 –

関連する問題