簡體   English   中英

提升Mutex Scoped Lock

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM