C 多執行緒與鎖

2021-08-27 05:09:02 字數 2705 閱讀 9162

多執行緒是小型軟體開發必然的趨勢。c++11將多執行緒相關操作全部整合到標準庫中了,省去了某些坑庫的編譯,真是大大的方便了軟體開發。多執行緒這個庫簡單方便實用,下面給出簡單的例子

#include#include#includeusing namespace std;volatile int val;

mutex mut;

void icrement ()

}

int main (int argc, char* argv )

概念有點多。首先得引入thread與mutex這兩個標頭檔案,其中thread與執行緒有關,mutex與鎖有關。然後是兩個全域性變數,由於兩個執行緒都會訪問,所以加上volatile關鍵字,代表不要對這變數進行優化,然後是mutex,這個就是鎖咯。

然後,下面的main函式中,首先建立兩個執行緒,然後等待兩個執行緒執行完,然後輸出結果。最後是increment函式,這函式迴圈一億次,不停的加鎖解鎖,控制著val變數的訪問。鎖還提供乙個函式,比如這樣呼叫 mut.try_lock (); ,立即返回bool型別,true代表加鎖成功,false代表加鎖失敗。

這是最基本的情況。對於普通的加鎖解鎖操作,使用lock、unlock就夠用了。但如果分支太多,這個就不好控制了。c++11提供了一種自動鎖的機制,比如上面**可以替換成這樣:

void icrement ()}自動鎖就不用刻意的解鎖了,對於多分支的情況相當方便。

除了普通的鎖之外,還有三種鎖:

recursive_mutex rm;//遞迴鎖recursive_timed_mutex rtm;//遞迴超時鎖timed_mutex tm;//超時鎖遞迴鎖用在遞迴的場合,超時鎖也就是普通鎖加上超時功能,基本功能與鎖相同。

鎖方便控制**邏輯,但如果只是控制訪問乙個變數的話,有一種更好的選擇,那就是原子。詳見c++11:原子操作

關於**邏輯的控制,除了thread之外,還有一種,std::async,用於接收執行緒函式的返回值。關於返回值,通過thread的引用引數也可以傳遞,std::async只是讓**邏輯更清晰而已。示例**如下:

#include#include#includeint main (int argc, char* argv ) );std::future_status status;

do else if (status == std::future_status::timeout) else if (status == std::future_status::deferred)

} while (status != std::future_status::ready);

std::cout << future.get () << std::endl;

return 0;

}

使用async首先需要引入future這個標頭檔案。然後是std::async這個函式,它返回乙個std::future這個模板型別,型別取決於函式的返回值。

第乙個引數代表啟動方式,std::launch::async代表呼叫函式時啟動,std::launch::deferred代表建立後掛起執行緒,當執行std::future<>.get()時才執行執行緒。

第二個引數傳入函式,可以是函式位址、lambda表示式或仿函式等。如果有引數的話,可以在呼叫std::async時加引數就行了。

這個執行緒執行兩句話,sleep_for這行的意思是執行緒暫停3秒。個人感覺這語法太複雜了,還不如微軟sleep來的簡潔。暫停執行緒之後,直接返回4。

然後 我們定義乙個future的狀態,future_status,用於獲取執行緒執行結果。這兒可以直接用get(),表示等待執行緒執行完,那麼就不用future了,也跟單執行緒沒區別了,所以還是用wait_for來獲取狀態。獲取狀態後進行判斷。如果為std::future_status::ready,代表執行緒已經執行完畢;如果為std::future_status::timeout,表示等待了wait_for傳入的時間之後,執行緒還沒執行完畢,還在繼續執行;如果為std::future_status::deferred,代表執行緒還處於掛起狀態。我用的vs2013 communicaty update4,發現無論如何也無法處於std::future_status::deferred狀態,據說是我這個版本的bug,在vs2015中修復。個人建議,掛起執行緒這個盡量不用,呼叫get來獲取還不如直接單執行緒來的直接。

然後是future.get,用於獲取執行緒的返回值。如果執行緒並沒執行完那麼就一直等著。除此之外還有乙個相似的函式,wait,用來等待執行緒執行結束,效果差不多。

以上**不出所料,執行結果如下:

C 11 多執行緒與鎖

多執行緒是小型軟體開發必然的趨勢。c 11將多執行緒相關操作全部整合到標準庫中了,省去了某些坑庫的編譯,真是大大的方便了軟體開發。多執行緒這個庫簡單方便實用,下面給出簡單的例子 include include include using namespace std volatile int val ...

多執行緒同步與鎖

多執行緒同步與鎖 本次主要討論的是lock,autoeventset,moniter 如下 上圖為執行緒1,2執行write1,被阻塞,直到執行緒4發出訊號,執行緒1,2收到訊號後取得執行權的執行緒可以執行 改下main 上圖為執行緒3,5執行write2,執行緒4執行wirte4,首先取得lock...

C 多執行緒 巢狀鎖

巢狀鎖這個概念,主要是為了根據程式設計中的一種情形引申出來的。什麼情況呢,我們可以具體說明一下。假設你在處理乙個公共函式的時候,因為中間涉及公共資料,所以你加了乙個鎖。但是,有一點比較悲哀。這個公共函式自身也加了乙個鎖,而且和你加的鎖是一樣的。所以,除非你的使用的是訊號量,要不然你的程式一輩子也獲取...