c++線程學習-1

《C++ Concurrencyin Action》讀書筆記

1、使用g++編譯多線程程序的時候需要加上-lpthread參數,如:

g++ -std=c++11–o run.out test.cpp –lpthread

2、多線程編程增加了頭文件#include<thread>,標準c++庫中對多線程支持的聲明在新的頭文件中,管理現成的函數和類在<thread>中聲明,而保護共享數據的函數和類在其他頭文件中聲明。每個線程都必須具有一個初始函數,新線程的執行在這裏開始,一般初始線程的main()函數,對於其他線程,可以在std::thread對象的構造函數中指定。

例子:

#include<iostream>

#include<thread>

using namespace std;

 

void thread_hello()

{

Cout <<“hello thread”<<endl;

}

Int main(void)

{

       Threadt(thread_hello);

t.join();

//t.detach();

return 0;

}//end

Join:線程的加入,可以確保線程在函數完成前結束,能保證局部變量在縣城完成後才被銷燬;jion()只能對給定的對象調用一次,如果對給已加入的線程再次join()操作時,將會導致錯誤,可以調用joinable()進行判斷是否已經加入。

Detach:線程的分離,主調函數不等待線程結束。使用detach()會讓線程在後臺運行,意味着主線程不能與之直接交互。通常分離線程爲守護線程(沒有任何用戶接口,並在後臺運行的線程)。

3、在把函數對象傳入到線程構造函數中時,需要注意:如果傳遞了一個臨時變量(非命名的變量),c++編譯器會將其解析爲函數生命,而不是類型對象的定義,例如:

       Std::threadmy_thread(test_thread());

這裏相當於聲明瞭一個帶有一個參數名爲my_thread並但會一個std::thread對象的函數。解決這個問題的四種方式:

1) 在前面命名函數對象;

2) 使用多組括號,std::thread my_thread((test_thread()));

3) 使用c++11新的初始化語法:std::thread my_thread{test_thread()};//大括號括起來;

4) 使用lambda表達式(允許使用一個可以捕獲局部變量的局部函數)。

 

4、爲了防止主調函數執行完成後(使用了detach),新線程還在運行(可能會訪問到已經銷燬的變量),常規方法:使線程函數的功能齊全,將數據複製到縣城中,而不是複製到共享數據中(引用和指針的不當使用)。

5、什麼情況下使用分離線程:一個程序執行多個相同的線程人物,每個線程運行相同的代碼,但是每個線程都是獨立的,完成與否對其他線程都不會產生影響。

6、向線程函數傳遞參數,例:

     Void func(int i , std::string const&s);

     Std::thread t(func, 3, “hello”);//注意字面值常量(char const *)向std::string對象的轉化

還可以傳遞一個成員函數指針作爲線程函數,並提供一個合適的對象指針作爲第一個參數。

7、不能通過賦一個新值給std::thread對象的方式來“丟棄”一個線程,std::thread支持移動,就意味着新線程的所有權可以在函數外進行轉移。例:

Std::thread f()

{

     Void some_func();

     Return std::thread(some_func);

/*或者如下定義:

*std::thread t(some_func);

*return t;*/

}

8、當所有權可以在函數內部傳遞,就允許std::thread實例可作爲參數進行傳遞。例:

Void f(std::threadt);

F(std::thread(some_function));

9、std::thread::hardware_concurrency(),該函數返回能同時併發在一個程序中的線程數量(多核系統中,返回值是cpu核心的數量)。

10、在確定了要使用的線程數量之後,通過創建一個std::vector<T>容器存放中間結果,併爲線程創建一個std::vector<std::thread>容器,需要注意:啓動線程的數量必須比num_threads小1,因爲在啓動之前已經有了一個主線程。

11、線程標識類型是std::thread::id,以兩種方式可以獲取:

     1)通過調用std::thread對象的成員函數get_id()來直接過去,如果std::thread對象沒有與任何執行線程相關聯,get_id()將返回std::thread::type默認構造值,這個值表示沒有線程

     2)當前線程中調用std::this_thread::get_id()(該函數也定義在<thread>頭文件中)。

Std::thread::id對象可以自由的拷貝和對比,因爲標識符就可以複用。如果兩個對象的std::thread::id相等,那它們就是同一個線程,或者都沒有線程。如果不等,那麼就代表了兩個不同線程,或者一個有線程一個沒有。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章