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多线程$

 

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