1, 创建一个线程
1.1 可以通过函数指针创建
#include <thread>
#include <iostream>
static void worker1(){
for (int i = 0; i < 10; ++i) {
std::cout << "worker " << i << std::endl;
}
}
int main() {
std::thread t1 = std::thread(worker1);
if (t1.joinable()){
std::cout << "wait worker1" << std::endl;
t1.join();
}
std::cout << "===end===" << std::endl;
return 0;
}
此处使用了join函数来测试线程的创建,如果不适用main函数的线程会限于worker1结束。
打印如下(多次)
此处可以发现worker1线程和主线程是同时执行的,也就是说worker1和主线程同时在向打印输出流中输出内容,而导致不一致。如果想要一致则必须要使得worker1和主线程完成同步(之后讨论)。
1.2 可以通过对象来创建
通过类的实例化对象来实现线程,其实是对()操作符的重载操作来实现线程的启动,这里我们需要注意一点,该对象是通过复制到新的线程中来执行的而不是原来的对象被执行,这一点我们可以通过复制构造函数来检测。
class worker2 {
public:
worker2(){
count++;
}
worker2(worker2 const& w2) {
count++;
}
void operator() () {
std::cout << "worker2 " << "[" << count << "]"<< std::endl;
}
static int count;
};
int worker2::count = 0;
/* worker2 test */
worker2 w2 = worker2(); //...................1
w2();
std::thread t2 = std::thread( w2 ); //................2
if (t2.joinable()) {
//std::cout << "wait worker2" << std::endl;
t2.join();
}
结果:
这里我们设置了一个全局变量来辅助我们检测,首先在1处worker2的构造函数被调用count++,在2处worker2的复制构造函数被调用count++。这意味着如果我们以对象的形式创建线程,一定要注意它仅仅是一个copy在另一个栈空间中重新执行,如果有指针务必检查使用以免出现悬垂指针。
1.3 可以通过Lambda来创建
其实就是匿名函数,相当灵活。
std::thread t3 = std::thread([](int x) {
std::cout << "worker3 working..." << "[" << x << "]" << std::endl;
},33);
if (t3.joinable</