日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

boost Mutex

發布時間:2023/12/20 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 boost Mutex 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

寫過多線程程序的人都知道,不能讓多個線程同時訪問共享的資源是至關重要的。

假如一個線程試圖改變共享數據的值,而另外一個線程試圖去讀取該共享數據的值,結果將是未定義的。

為了阻止這樣的事情發生,需要用到一些非凡的原始數據類型和操作。其中最重的一個就是總所周知的mutex(“mutual exclusion的縮寫。譯注:相互排斥的意思,經常被翻譯為互斥體”)

mutex在同一時間只能答應一個線程訪問共享資源。當一個線程需要訪問共享資源時,它必須先鎖住”mutex,假如任何其他線程已經鎖住了mutex,那么本操作將會一直被阻塞,直到鎖住了mutex的線程解鎖,這就保證了共享資源,在同一時間,只有一個線程可以訪問。

mutex的概念有幾個變種。Boost.Threads支持兩大類型的mutex簡單mutex和遞歸mutex。一個簡單的mutex只能被鎖住一次,假如同一線程試圖兩次鎖定mutex,將會產生死鎖。對于遞歸mutex,一個線程可以多次鎖定一個mutex,但必須以同樣的次數對mutex進行解鎖,否則其他線程將無法鎖定該mutex。

在上述兩大類mutex的基礎上,一個線程如何鎖定一個mutex也有些不同變化。一個線程有3種可能方法來鎖定mutex

1.?等待并試圖對mutex加鎖,直到沒有其他線程鎖定mutex

2.?試圖對mutex加鎖,并立即返回,假如其他線程鎖定了mutex

3.?等待并試圖對mutex加鎖,直到沒有其他線程鎖定mutex或者直到規定的時間已過。


看起來最好的mutex類型是遞歸的mutex了,因為上述3種加鎖的方式它都支持。不過,不同的加鎖方式有不同的消耗,因此對于特定的應用,Boost.Threads答應你挑選最有效率的mutex。

為此,Boost.Threads提供了6中類型的mutex,效率由排列:

boost::mutex

boost::try_mutex

boost::timed_mutex

boost::recursive_mutex

boost::recursive_try_mutex

boost::recursive_timed_mutex。

假如一個線程鎖定一個mutex后,而沒有解鎖,就會發生死鎖,這也是最為常見的錯誤了,為此,Boost.Threads專門進行了設計,可不直接對mutex加鎖或者解鎖操作,以使這種錯誤不可能發生(或至少很難發生)

取而代之地,mutex類定義了內嵌的typedef來實現RAII(Resource Acquisition In Initialization,譯注:在初始化時資源獲得)[4]用以對一個mutex進行加鎖或者解鎖,這就是所謂的Scoped Lock模式。要構建一個這種類型的鎖,需要傳送一個mutex引用,構造函數將鎖定mutex,析構函數將解鎖mutex。C++語言規范確保了析構函數總是會被調用,所以即使有異常拋出,mutex也會被正確地解鎖。

這種模式確保了mutex的正確使用。不過必須清楚,盡管Scoped Lock模式保證了mutex被正確解鎖,但它不能保證在有異常拋出的時候,所有共享資源任然處于有效的狀態,所以,就像進行單線程編程一樣,必須確保異常不會讓程序處于不一致的狀態。同時,鎖對象不能傳送給另外一個線程,因為他們所維護的狀態不會受到此種用法的保護。


列表2舉例說明了boost::mutex類的一個簡單的用法。其中兩個線程被創建,每個循環10次,將id和當前循環計數輸出到std::coutmain線程等待著兩個線程結束。std::cout對象是一個共享資源,所以每個線程均使用全局mutex,以確保在同一時刻,只有一個線程輸出到它。

#include?<boost/thread/thread.hpp>

#include?<boost/thread/mutex.hpp>

#include?<iostream>

boost::mutex?io_mutex;

struct?count

{

? ? count(int?id) : id(id) { }

? ? void?operator()()

? ? {

? ? ? ? ?for?(int?i = 0; i < 10; ++i)

? ? ? ??{

? ? ? ? ? ? boost::mutex::scoped_lock?lock(io_mutex);

? ? ? ? ? ? std::cout << id <<?": "?<< i << std::endl;

? ? ? ??}

? ? }

? ? int?id;

};

int?main(int?argc,?char* argv[])

{

? ? boost::thread thrd1(count(1));

? ? boost::thread thrd2(count(2));

? ? thrd1.join(); //函數來等待線程結束

? ? thrd2.join();

? ? return?0;

}

列表2

也許你已經注重到在列表2的代碼中,需要手工寫一個函數對象,才能向線程傳送數據。盡管代碼很簡單,但每次都要寫這樣的代碼也會讓人有單調沉悶之感。有另外一種更輕易的解決辦法,Functional庫可以讓你通過將需要傳入的數據綁定到另外一個函數對象的方式,來創建一個新的函數對象。列表3展現了Boost.Bind庫如何不寫函數對象,而簡化列表2中的代碼。

// This program is identical to listing2.cpp except that it uses

// Boost.Bind to simplify the creation of a thread that takes data.

#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;

}

總結

以上是生活随笔為你收集整理的boost Mutex的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。