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;
}
Lei Yang
Lei Yang
PhD candidate

My research interests include visual speech recognition and semantics segmentation.