2013-04-10 44 views
0

因此,我正在閱讀關於同步並且遇到了監視器,但似乎無法掌握它們的工作方式。Monitor Synchronization如何工作?

我看到的總體佈局是什麼與什麼我可以爲條件變量看到下面的格式(我真的不知道這是什麼做的):

monitor { 
    // shared variables 
    procedure P1 (..) {..} 
    ... 
    procedure P2 (..) {..} 
    initialisation code (..) {..} 
} 

然而,隨着就像我猛撞我的頭,我看不到如何描述這樣的監視器一次只允許一個進程訪問。

回答

1

我喜歡將監視器想象成具有私有互斥鎖的對象,並且每個過程都受該互斥鎖的保護。因此,像:

MyClass { 
    // private shared variables 
    ... 
    mutex m; 
    // public procedures 
    Procedure P1(...) { 
    acquire(m); 
    ... 
    release(m); 
    } 
    Procedure P2(...) { 
    acquire(m); 
    ... 
    release(m); 
    } 
    initialisation code (...) { ... } 
} 

的互斥體,保證在某時刻只有一個線程/進程可以被操縱的對象,因爲每一個公共程序是包裹着互斥鎖獲取/釋放。

那麼這些條件變量呢?那麼,你通常不需要它們。但是有時你有一些條件,一個線程需要等待另一個線程,這就是條件變量進入的地方。

假設例如您正在實現併發隊列對象。您將有一個push()程序和一個pop()程序。但是如果隊列是空的,你應該怎麼做?

它不會工作,有獨立的空()和pop()方法,因爲這樣的代碼,:

Thread A    Thread B 
if (not q.empty()) 
         if (not q.empty()) 
         then q.pop() // now q is empty! 
then q.pop() // error! 

所以,你必須定義它返回一個特殊值的pop()方法步驟當隊列爲空時,然後旋轉等待隊列變爲非空。但旋轉等待效率非常低。

因此,您可以使用條件變量。條件變量有兩種方法:wait()notify()。 Wait()以原子方式放棄所持有的互斥鎖,然後阻塞該線程,直到某些其他線程調用notify()。所以像這樣的:

condition_variable cv; 
Procedure int pop() { 
    acquire(m); 
    while (q.empty()) { 
    wait(cv, m) // atomically release m and wait for a notify() on cv. 
    // when wait() returns it automatically reacquires mutex m for us. 
    } 
    rval = q.pop(); 
    release(m); 
    return rval; 
} 
Procedure push(int x) { 
    acquire(m); 
    q.push(x); 
    notify(cv); // wake up everyone waiting on cv 
    release(m); 
} 

現在你有一個數據結構/對象,其中只有一個線程可以在同一時間內訪問對象,並在不同的線程之間的操作都需要在一個發生,你可以照顧的情況下,特定的順序(如至少一個push()必須在每個pop()完成之前發生。)