2015-07-21 125 views
0

的ThreadA通過這個片段是否調用pthread_mutex_lock有之前發生的語義

{ 
    global_a = 100; // 1 
    { 
     pthread_mutex_lock(&b_mutex) 
       ... 
     pthread_mutex_unlock(&b_mutex) 
    } // 2 
} 

threadB通過這個片段

{ 
    { 
     pthread_mutex_lock(&b_mutex) 
       ... 
     pthread_mutex_unlock(&b_mutex) 
    } // 3 

    int tmp = global_a; // 4 
} 

,並假設從觀察者觀看確實執行順序

  1. threadA --- 1
  2. threadA --- 2
  3. threadB --- 3
  4. threadB --- 4

可以在threadB "int tmp = global_a;"代碼中看到什麼的ThreadA設定在"global_a = 100;"

任何建議是值得歡迎的。

回答

1

pthread_mutex_lock並不妨礙以前的指令要在它後面下單。

類似的,pthread_mutex_unlock不會阻止跟着指令在它之前被排序。

但是:

  1. ThreadA中global_a = 100之前發生pthread_mutex_unlock(&b_mutex)

  2. 在線程B pthread_mutex_lock(&b_mutex)發生在int tmp = global_a;

如果你觀察

  • pthread_mutex_unlock(&b_mutex) ThreadA中pthread_mutex_lock(&b_mutex)在threadB之前發生。
  • (換言之,threadB aquires鎖定的ThreadA釋放後),然後

    global_a = 100; ThreadA中之前發生int tmp = global_a;在threadB。所以,最後一個看到第一個的效果。

    什麼POSIX標準說:

    至於POSIX標準同步的細節,我發現的唯一參考值(和其他人蔘考)約爲Memory Synchronization短章。它說,pthread_mutex_lock(和其他一些功能)

    同步內存相對於其他線程

    某人的解釋爲完全內存屏障 garantee,其他人(和我)喜歡思考一些經典 garantees當鎖定和等待動作提供內存獲取語義,解鎖和通知的 - 內存釋放語義。參見,例如,這個mail

    沒有之前發生在POSIX項。但它可以像往常一樣定義,考慮到內存訂單保證(在一個人的說明中)。

    +0

    證明是偉大的,但如果是這樣定義的**之前發生**和** ** transitiviy通過**的之前發生**與'pthread_mutex_lock'和'pthread_mutex_unlock'?我有谷歌,但沒有。你能告訴我一些關於它的參考嗎? – Alex

    +0

    我在我的答案中添加了一些參考。 POSIX沒有定義*發生前*期限,但它可以根據內存順序保證來定義。 – Tsyvarev

    1

    如果您可以保證執行順序 - 當是。如果你能保證執行順序,你甚至不需要鎖定某些體系結構。

    鎖實際上做三件事情: 1.不要允許執行不同的代碼同時。看到。這裏沒有提到記憶。它只是保證不同線程中的代碼不會被同時執行。 2.在某些體系結構中,它將插入緩存一致性指令。這迫使多個處理器系統將數據刷新到實際內存中。但您現在不應該擔心這種情況「如果所有寫入同一內​​存位置的操作都按照某種順序執行,則多處理器的緩存保持一致」 3.插入內存屏障指令。這是爲了處理器,告訴它不要混淆執行順序。

    而且你編譯器可制動的事情爲好。所以把你的變量聲明爲volatile。

    +0

    最後用「所以聲明你的變量爲volatile」,你的意思是可能是threadB「int tmp = global_a;」 **不能**看到在「global_a = 100;」處設置了什麼線程 – Alex

    相關問題