Cpp Concurrency學習筆記1——啓動新線程

1,引入

C++11中引入了多線程的概念,從此以後編寫多線程不一定要用linux的pthread庫了。從入職的兩家公司看,目前也是推薦使用C++語言的多線程解決方案,而不是linux的解決方案。

C++多線程用到的頭文件是 <thread>,需要注意的是,編譯的時候除了制定C++標準爲C++11外,還要加上-pthread選項,或者直接使用-lpthread(所以推測C++底層用的應該還是linux的pthread庫吧)。

2,一個啓動多線程的例子

我們啓動一個新的線程去執行某個函數。分成函數無參數、值傳遞參數和引用傳遞參數3種情況。

簡單來說,創建thread對象,把函數和參數作爲thread對象的構造函數的參數傳遞進去就OK了。

#include <iostream>
#include <thread>
#include <unistd.h>
#include <string>

using namespace std;

// 無參數
void Hello() {
    cout << "I am so over you, LBH." << endl;
    sleep(2); // 等待兩秒
    return;
}

// 有參數,值傳遞
void HelloWho(string name) {
    cout << "I am  " << name << endl;
    sleep(1); // 等待1秒
    return;
}

// 有參數,引用傳遞
void GetOld(unsigned& age) {
    ++age;
    cout << "過生日了。我今年" << age << endl;
    return;
}

int main() {
    cout << "I am in main thread " << endl;
    string str("林碧涵");
    unsigned age = 18;

    // 將Hello函數放入新線程,無參數傳遞
    thread t1(Hello); // 將hello函數放入新線程運行

    // 對線程進行值傳遞
    thread t2(HelloWho, str); 

    // 對線程進行引用傳遞
    // 由於下面是在構建thread對象,如果不使用std::ref,那麼進行的就是值傳遞
    thread t3(GetOld, ref(age)); // 可以通過引用修改main中的局部變量,因爲共享地址空間

    t3.join();
    cout << "t3返回 " << endl;

    t2.join(); // 等待新線程返回
    cout << "t2返回 " << endl;
    
    t1.join();
    cout << "我胡漢三又回來了, age = " << age << endl;

    return 0;
}

需要做幾點說明:

  1. join()函數表示主線阻塞直到新線程返回。當然我試過,如果新線程已經返回,主線程才調用join也沒什麼問題,此時join是馬上返回;
  2. 在應用傳遞的例子中,我們使用了std::ref這個模板函數。因爲thread t3(GetOld, ref(age))首先是在定義一個thread對象,而thread的構造函數是不知道你是引用的。所以如果不用std::ref,則實際上還是值傳遞。在我的編譯器下,不用std::ref甚至根本編譯不過去,除非你把GetOld改成值傳遞或者const引用;

將上述代碼保存成main.cpp,編譯的指令如下:

g++ main.cpp -g -Wall -std=c++11 -pthread -o main

注意“-pthread”這個選項。沒有這個選項編譯是無法成功的。

執行結果如下:

huangyang@狗蛋:~/code/CppConcurrency/Cp2多線程$ ./main
I am in main thread
I am so over you, LBH.
I am  林碧涵
過生日了。我今年19
t3返回
t2返回
我胡漢三又回來了, age = 19
huangyang@狗蛋:~/code/CppConcurrency/Cp2多線程$

 

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