C++多线程编程笔记

基本使用

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <thread>
#include <chrono>

using namespace std;

void read_val(int &val) {
while (true) {
cin >> val;
this_thread::sleep_for(chrono::seconds(1));
}
}

int main(int argc, char** argv) {
int val(0);
thread read_thread(read_val, ref(val));
while (true) {
cout << val << endl;;
this_thread::sleep_for(chrono::seconds(1));
}
return 0;
}

使用g++编译:

1
g++ -std=c++11 test.cpp -lpthread -o test

thread类构造函数第一个参数为线程所跑函数名,后面接所跑函数参数,需要注意的是引用类型需要通过std::ref传入。

可以通过定义一个全局的mutex类,通过该类的lock()和unlock()进行上锁和解锁,但如果在lock和unlock之间程序发生异常容易造成死锁。因此,通常我们使用lock_guard类来控制mutex,利用lock_guard的析构函数来解锁。unique_lock相比与lock_guard提供了更多接口,并且可以用来处理多个锁的上锁解锁情况,避免出现多个锁造成的死锁。

Lazy Initialization

代码示例:

1
2
std::once_flag flag;
std::call_once(flag, [&](){return;});

通过使用call_once可以实现只调用一次所给函数,并且保证了线程安全。

条件变量

条件变量可以控制线程的执行顺序,通过定义全局的条件变量std::condition_variable,在线程中分别通过notify_once/notify_all和wait函数触发和等待触发相关操作。

线程间数据输入与输出

通过std::async函数和future、promise变量可以实现线程间数据输入输出。