c++11 thread 新线程的启动很简单,创建线程对象时,传入函数或类对象即可,如:
#include <stdio.h>
#include <stdlib.h>
#include <thread>
#include <sys/syscall.h>
#include <unistd.h>
class CBackgroundTask
{
public:
void operator()() const
{
printf("in new thread %lu\n", syscall(SYS_gettid));
}
void funcProc()
{
printf("in new thread %lu\n", syscall(SYS_gettid));
}
};
void funcPro()
{
printf("in new thread %lu\n", syscall(SYS_gettid));
}
int main()
{
CBackgroundTask task;
std::thread threadTest(task);
std::thread threadTest1(funcPro);
CBackgroundTask task1;
std::thread threadTest2(std::bind(&CBackgroundTask::funcProc, task1));
threadTest.join();
threadTest1.join();
threadTest2.join();
return 0;
}
如上代码列举了创建新线程:
1,从类的重载运算符() 启动,如:
CBackgroundTask task;
std::thread threadTest(task);
2,从普通函数启动,如:std::thread threadTest1(funcPro);
3,从类的public 函数启动,如:
CBackgroundTask task1;
std::thread threadTest2(std::bind(&CBackgroundTask::funcProc, task1));
还有一种 lambda 表达式,这里没写出来,以后再说。
我们注意到,第一种启动方式我们是定义了一个临时对象,然后作为参数传给线程类的构造函数,那是否可以在线程构造函数里直接调用对象的构造函数创建临时变量呢?答案是可以的,但需要注意。如下一个表达式:
std::thread threadTest(CBackgroundTask()); 这个语句写得是没有问题的,假如上面的代码相应的改成这样,编译结果如何呢?
这里只是说 join 用得不对,如果去掉对应的 threadTest.join(); 再编译是没有问题的且运行如下:
只创建了 2 个新的线程。而语句 std::thread threadTest(CBackgroundTask()); 被编译器解释成了函数声明,而非线程变量的定义,是声明了一个函数,其参数类型是指向不接受参数同时返回CBackgroundTask 对象的函数的指针,并返回 std::thread 对象。要避免这种情况,可以有两种方法:
1,增加一对括号,如:
std::thread threadTest((CBackgroundTask()));
2,c++11 新的初始化语法,如:
std::thread threadTest{(CBackgroundTask())};
还有一种是 lambda 语法,这里不作介绍。