[英]Boost Mutex Scoped Lock
我正在閱讀drdobbs.com上的Boost Mutex教程,並發現了這段代碼:
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <iostream>
boost::mutex io_mutex;
void count(int id)
{
for (int i = 0; i < 10; ++i)
{
boost::mutex::scoped_lock
lock(io_mutex);
std::cout << id << ": " <<
i << std::endl;
}
}
int main(int argc, char* argv[])
{
boost::thread thrd1(
boost::bind(&count, 1));
boost::thread thrd2(
boost::bind(&count, 2));
thrd1.join();
thrd2.join();
return 0;
}
現在我明白Mutex的意思是阻止兩個線程同時訪問同一個資源,但我沒有看到io_mutex和std :: cout之間的相關性。 這個代碼是否只是鎖定范圍內的所有內容,直到范圍完成為止?
現在我明白Mutex的意思是阻止兩個線程同時訪問同一個資源,但我沒有看到io_mutex和std :: cout之間的相關性。
std::cout
是一個全局對象 ,因此您可以將其視為共享資源。 如果從多個線程同時訪問它,則必須以某種方式同步這些訪問,以避免數據爭用和未定義的行為。
通過考慮以下情況,您可能會更容易注意到並發訪問:
std::cout << x
實際上相當於:
::operator << (std::cout, x)
這意味着您正在調用一個在std::cout
對象上運行的函數,並且您正在同時從不同的線程執行此操作。 必須以某種方式保護std::cout
。 但這並不是scoped_lock
存在的唯一原因(繼續閱讀)。
這個代碼是否只是鎖定范圍內的所有內容,直到范圍完成為止?
是的,它會鎖定io_mutex
直到鎖定對象本身超出范圍(作為典型的RAII包裝器),這發生在for循環的每次迭代結束時。
為什么需要它? 好吧,盡管在C ++ 11中,單個插入到cout
中的插入保證是線程安全的,但是當幾個線程輸出某些內容時,后續的單獨插入可能會交錯。
請記住,每個通過operator <<
插入都是一個單獨的函數調用,就像你在做的那樣:
std::cout << id;
std::cout << ": ";
std::cout << i;
std::cout << endl;
operator <<
返回流對象的事實允許您在單個表達式中鏈接上述函數調用(就像您在程序中所做的那樣),但是您仍然擁有幾個單獨的函數調用這一事實。
現在看一下上面的代碼片段,更明顯的是這個范圍鎖的目的是確保表單中的每條消息:
<id> ": " <index> <endl>
獲取打印時不將其部分與其他消息中的部分交錯。
此外,在C ++ 03中(其中插入到cout
中並不保證是線程安全的),鎖將保護cout
對象本身不被同時訪問。
互斥鎖與程序中的任何其他內容(條件變量除外)無關,至少在更高級別。 互斥鎖有兩個有效之處:它控制程序流,並防止多個線程同時執行相同的代碼塊。 它還確保了內存同步。 這里的重要問題是互斥體與資源無關,並且不會阻止兩個線程同時訪問同一資源。 互斥鎖定義代碼的關鍵部分,一次只能由一個線程輸入。 如果在由相同互斥鎖控制的關鍵部分中完成對特定資源的所有使用,則該資源將受到互斥鎖的有效保護。 但是這種關系是由編碼人員確定的,確保所有使用確實發生在關鍵部分。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.