template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
这个是std::thread构造函数之一,其中f是可调用对象,args是传递给f的参数。
默认传递给f的是按值复制,若需要传递引用参数给线程函数,则必须包装它(例如用 std::ref 或 std::cref )。
f类型:
- 普通函数
- 类成员函数
args分类:
- 引用传递
- 按值传递
普通函数
普通函数的示例如下
//按值传递
void FunbyCopy(int num)
{
++num;
}
//引用传递
void FunbyRef(int & num)
{
++num;
}
//测试代码
int num = 10;
//按值传递
std::thread task1(FunbyCopy, num);
std::cout << "num is " << num << std::endl;
//没有用ref包装,被认为是按值传递
std::thread task2(FunbyRef, num);
std::cout << "num is " << num << std::endl;
//引用传递
std::thread task3(FunbyRef, std::ref(num));
std::cout << "num is " << num << std::endl;
task1.join();
task2.join();
task3.join();
运行结果
num is 10
num is 10
num is 11
类成员函数指针
f可以传递一个成员函数指针作为线程函数,并提供一个合适的对象指针,之后传递的是线程函数的参数。参数形式可以是引用或者按值传递。
具体使用如下:
//测试类
class CMath
{
public:
CMath(int _a, int _b) :a(_a), b(_b){}
CMath(){}
~CMath(){}
void add_sum(){sum = a + b;}
int get_sum(){return sum;}
void set_a(int _a){ a = _a;}
void set_b(int _b){ b = _b;}
private:
int a;
int b;
int sum;
};
测试代码
CMath math;
//设置值
math.set_a(20);
math.set_b(20);
//启动线程计算值
//构造函数的第一个参数是类成员指针,第二个参数是类对象指针
//如果需要给成员指针传递参数,则从第三个参数开始
std::thread cal_task(&CMath::add_sum, &math);
//等待计算结束
cal_task.join();
//输出结果
std::cout << "sum is " << math.get_sum() << std::endl;
运行结果:
sum is 40
总结
使用类成员函数指针作为线程函数,是以面向对象的方式进行编码,在复杂类中使用成员函数指针可能会比较方便。如果是简单的逻辑,使用普通函数的形式就可了。如有不足,欢迎大家指正~