C 11多執行緒學習 執行緒函式的引數傳遞

2021-08-09 09:17:18 字數 1435 閱讀 1870

執行緒引數傳遞要記住乙個重要的事情,傳遞的引數是存在新執行緒乙個內部的轉存站中,之後在函式執行的時候再傳遞給函式本身的。

這種機制會引發兩個問題:

1.臨時引數的未及時構造

void f(int i,std::string const& s);

void oops(int some_param)

雖然函式f的第二個引數接受的是乙個std::string,但是我們傳遞進去的是乙個char*,而這個char*在建立這個執行緒的時候並不會直接就轉換為std::string.這裡出現的問題就是呼叫時機與傳遞引數的時機不一致所導致的,所以一種更安全的寫法是先把這個string構造好:

void f(int i,std::string const& s);

void oops(int some_param)

這種做法保證了現將buffer構造好string,隨後執行緒傳遞的時候傳遞string就不會有這個問題。

2.傳遞引用時無法修改引用的資料

void update_data_for_widget(widget_data& data);//函式接受的引數是引用

void oops_again()

雖然update_data_for_widget這個函式接受的是引用,可以修改data的值。但是當我們把data傳入std::thread的建構函式時,拷貝構造就已經發生了。也就是說,最後update_data_for_widget這個函式處理的只是乙份拷貝,根本就不會修改原始的值。所以在這種場景下,我們可以採用以std::ref的形式傳遞引用。相當於在引用上面做了一層物件封裝,單純的傳遞物件依舊可以修改原始的值:

std:thread t(update_data_for_widget,std::ref(data));

另外,執行緒如果像傳遞乙個成員函式作為引數,其形式類似於bing的形式:

class x

x my_x;

std::thread t(&x::do_lengthy_work,&my_x);

對於引數有std::move的需求,對於臨時變數將會自動呼叫,對於有名字的變數我們可以採用std::move()來要求執行。

同樣的,std::thread物件是乙個只可以移動,不可以拷貝的物件。這裡注意乙個場景:如果乙個物件已經被初始化後,又被賦予其他的物件,就會產生問題:

std::thread t1(test_function);

std::thread t2(test_function);

t1 = std::move(t2);

這裡執行的第三句是程式就會異常退出,因為t1已經有了物件並且在釋放這個執行緒前沒有呼叫任何的detach() or join().

C 11 多執行緒

新特性之描述 雖然 c 11 會在語言的定義上提供乙個記憶體模型以支援執行緒,但執行緒的使用主要將以 c 11 標準庫的方式呈現。c 11 標準庫會提供型別 thread std thread 若要執行乙個執行緒,可以建立乙個型別 thread 的實體,其初始引數為乙個函式物件,以及該函式物件所需要...

c 11 多執行緒

1.多執行緒的原理 同一時間內,cpu只能處理1條執行緒,只有1條執行緒在工作 執行 多執行緒併發 同時 執行,其實是cpu快速地在多條執行緒之間排程 切換 如果cpu排程執行緒的時間足夠快,就造成了多執行緒併發執行的假象。思考 如果執行緒非常非常多,會發生什麼情況?cpu會在n多執行緒之間排程,c...

C 11 多執行緒

2011 年 c 迎來重大的改革 語言層面上承認了 多執行緒 程式的存在 加入了 thread 多執行緒支援庫,內容豐富 功能強大。首先從我個人理解角度粗鄙的理解一下多執行緒。多執行緒眾所周知 切割時間片的多程式併發執行,大多數的計算機都支援多執行緒併發的硬體支援。這可能是最簡單的多執行緒程式了。多...