抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Hello World

人よ、幸福に生きろ!

C++11的std::thread

开门见山,cpp多线程使用方法就是使用C++11的thread进行多线程编程。

std::thread常用成员函数

构造&析构函数

函数 类别 作用
thread() 默认构造函数 创建一个线程
thread(thread&& x) 移动构造函数 构造一个与x相同的对象,会破环x对象
~thread() 析构函数 析构对象

常用成员函数

函数 作用
void join() 等待线程结束并清理资源(会阻塞)
bool joinable() 返回线程是否可以执行join函数
void detach() 将线程与调用其的线程分离,彼此独立执行(此函数必须在线程创建时立即调用,且调用此函数会使其不能被join)
std::thread::id_get_id 获取线程id
thread& operator=(thread &&rhs) 移动构造函数(如果对象是joinable的,那么会调用std::terminate)

注意事项

  • 线程是在thread对象被定义的时候开始执行的,而不是在调用join函数时才执行的,调用join函数只是阻塞等待线程结束并回收资源
  • 分离的线程(执行过detach的线程)会在调用它的线程结束或自己结束时释放资源
  • 线程会在函数运行后自动释放,不推荐利用其他方法强制结束线程,可能会因资源未释放而导致内存泄露。
  • 没有执行join或detach的线程在程序结束时会引发异常

std::atomic和std::mutex

作用:多个线程需要操作同一个变量时,防止产生竞争与冲突

std::mutex

std::mutex是C++中最基本的互斥量,一个线程将mutex锁住时,其他的线程就不能操作mutex,直到这个线程将mutex解锁。

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 <mutex>
using namespace std;
int n = 0;
mutex mtx;
void count10000() {
for (int i = 1; i <= 10000; i++) {
mtx.lock();
n++;
mtx.unlock();
}
}
int main() {
thread th[100];
for (thread &x : th)
x = thread(count10000);
for (thread &x : th)
x.join();
cout << n << endl;
return 0;
}

mutex的常用成员函数

函数 作用
void lock() 将mutex上锁。
如果mutex已经被其他线程上锁,
那么mutex已经被同一个线程锁住,
那么会产生死锁。
void unlock() 解锁mutex,释放其所有权。
如果有线程因为调用lock()不能上锁而被阻塞,则调用此函数会将mutex的主动权随机交给其中一个线程;
如果mutex不是被此线程上锁,那么会引发未定义的异常。
bool try_lock() 尝试将mutex上锁。
如果mutex未被上锁,则将其上锁并返回true;
如果mutex已被锁则返回false.

std::atomic

由于每个thread都要循环地加锁、解锁,我们使用std::atomic来提高效率。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <thread>
#include <atomic>
using namespace std;
//atomic<int> n = 0;原子变量不能使用拷贝构造
atomic<int> n;
void count10000() {
for (int i = 1; i <= 10000; i++) {
n++;
}
}
int main() {
thread th[100];
for (thread &x : th)
x = thread(count10000);
for (thread &x : th)
x.join();
cout << n << endl;
return 0;
}

原子操作 是最小的且不可并行化的操作。

这就意味着即使是多线程,也要像同步进行一样同步操作atomic对象,从而省去了mutex上锁、解锁的时间消耗。

std::async

std::future

std::promise

std::this_thread

评论