2011-09-10 137 views
0

我最近開始使用boost :: thread(WinXP,VS10,BoostPro),發現互斥鎖可以被任何線程解鎖,而不是隻由擁有它的線程解鎖。 此外,它接縫,基本lock_guard +互斥組合正在做一些內部計數多鎖()和解鎖(),但它不是一個大問題,我猜。Boost:可能從任何線程解鎖互斥鎖?

有人知道爲什麼它是這樣設計的嗎?這是故意的嗎? (或者有什麼毛病我的編譯環境/庫?)

示例應用程序:

#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

Boost文檔是很清楚,調用mutex.unlock的先決條件是「當前線程擁有這個」。這並不意味着違反該前提條件將導致異常/錯誤/崩潰(儘管對於調試版本來說它可能很好),但在這種情況下您不能依賴任何特定的行爲。

win32實現似乎使用原子指令來實現大部分互斥體的邏輯 - 大概是因爲在win32上對更復雜的互斥體類型(遞歸/定時)的有限支持。 Win32的本機關鍵部分只能用於簡單的互斥鎖(而Win32的本地互斥鎖對於進程內互斥體來說太重量級了)。

+0

所以我想我的開發環境是好的。我完全知道boost文檔中的內容,但我相信這種行爲會導致在大型應用程序中發現非常嚴重且難以檢測到的錯誤。文檔聲明本身不能防止編程錯誤。在我看來,至少應該在調試版本中聲明一些聲明,以及在這種情況下有關未定義行爲的文檔中的信息。再次感謝您的評論。 – Oedo808

+1

@ Oedo808除了您對Win32實現的評論之外。我相信1_55提升會使用Lamport的麪包店(http://en.wikipedia.org/wiki/Lamport's_bakery_algorithm)。 –