C++并发编程:线程创建和运行
使用C++11实现的标准线程库进行并发编程
#include <thread>
创建和结束线程
创建线程
使用thread类的构造函数创建线程
// initFunc 是线程中要执行的函数名
std::thread t(initFunc);
实际上,任何可执行的对象都可以被传入线程中
包括函数、可执行类/结构体等
// 可执行类的定义
class callable_class{
int &i;
callable_class(int &i_):i(i_){}
void operator()() const {
std::cout << "The value i have is " << i << std::endl;
}
}
函数传参
线程的iniFunc可以有多个参数
在构造函数中的函数指针后跟参数列表
注意,thread的构造函数默认按值传参,即复制到线程变量内部
如果initFunc需要引用传参 则要使用 std::ref()
如果形参和实参类型不同 则要显式使用类型转换
结束线程
选择线程分离或者结合
std::thread t(initFunc);
// 线程分离
// 显式决定不等待线程执行结束
t.detach();
// 线程结合
// 等待线程执行结束
t.join();
线程分离
分离后的线程无法通信无法直接控制
守护线程通常被分离,运行在后台
线程结合
通常需要保证所有的线程都被结合
一种方法是RAII(资源获取即初始化),使用一个保护类包裹
class thread_guard{
std::thread t;
public:
// 只允许显式类型转换
explicit thread_guard(std::thread t_):t(std::move(t_)){
if(!t.joinable)
throw std::logit_error("No thread");
}
// 保证程序/函数结束时线程被合并
~thread_guard(){t.join();}
// 不生成默认构造函数和赋值函数
thread_guard(thread_guard const &) = delete;
thread_guard& operator=(thread_guard const &) = delete;
}