C++11向线程函数传递参数

template< class Function, class... Args > 
explicit thread( Function&& f, Args&&... args );

这个是std::thread构造函数之一,其中f是可调用对象,args是传递给f的参数。
默认传递给f的是按值复制,若需要传递引用参数给线程函数,则必须包装它(例如用 std::ref 或 std::cref )。

f类型:

  1. 普通函数
  2. 类成员函数

args分类:

  1. 引用传递
  2. 按值传递

普通函数

普通函数的示例如下

//按值传递
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

总结

使用类成员函数指针作为线程函数,是以面向对象的方式进行编码,在复杂类中使用成员函数指针可能会比较方便。如果是简单的逻辑,使用普通函数的形式就可了。如有不足,欢迎大家指正~

<think>我们使用std::thread创建线程时,可以通过线程函数参数传递数据。传递参数的方式是向std::thread构造函数传递额外的参数。需要注意的是,参数会以默认的方式被复制(或移动)到线程内部存储,因此需要特别注意参数传递方式(值传递引用传递)以及对象的生命周期。根据引用[3]:std::thread在内部会创建传递给它的可调用对象的副本或移动版。传递参数时需要注意:1.如果希望线程函数引用方式接收参数,必须使用std::ref或std::cref进行包装,否则即使线程函数声明为引用,实际传递的也是副本。2.当传递指针时要特别注意,必须确保指针所指向的对象在线程执行期间一直有效(尤其是使用detach时)。3.传递类对象时,要注意类对象的可复制性或可移动性,以及是否需要避免复制(可以使用移动语义)。下面给出几个示例:示例1:传递基本类型(值传递)示例2:传递引用(使用std::ref)示例3:传递类对象(注意复制和移动)示例4:传递成员函数(需要传递实例指针)同时,根据引用[1][2][4],我们还会展示如何正确使用join或detach。</think> ### C++ 中使用 `std::thread` 传递参数线程函数的实现方法 在 C++ 中创建带参数线程时,可以通过 `std::thread` 构造函数直接传递参数。以下是完整的实现方法: #### 1. **基本参数传递** ```cpp #include <iostream> #include <thread> // 线程函数:值传递参数 void worker(int count, const std::string& message) { for (int i = 0; i < count; ++i) { std::cout << message << " (" << i+1 << "/" << count << ")\n"; } } int main() { // 启动线程传递参数 std::thread t(worker, 3, "Processing item"); // 等待线程完成 t.join(); return 0; } ``` #### 2. **引用传递参数** 需要使用 `std::ref` 包装引用: ```cpp #include <iostream> #include <thread> // 线程函数引用传递参数 void modifyData(int& value) { value *= 2; // 修改原始数据 std::cout << "New value: " << value << std::endl; } int main() { int data = 10; // 使用 std::ref 传递引用 std::thread t(modifyData, std::ref(data)); t.join(); std::cout << "Main thread value: " << data << std::endl; // 输出: 20 return 0; } ``` #### 3. **传递复杂对象** ```cpp #include <iostream> #include <thread> #include <vector> // 线程函数传递容器对象 void processVector(const std::vector<int>& vec) { int sum = 0; for (int num : vec) sum += num; std::cout << "Vector sum: " << sum << std::endl; } int main() { std::vector<int> numbers = {1, 2, 3, 4, 5}; // 移动语义传递大对象 std::thread t(processVector, std::move(numbers)); t.join(); // numbers 现在处于有效但未指定状态 return 0; } ``` #### 4. **传递类成员函数** ```cpp #include <iostream> #include <thread> class Task { public: void execute(int priority) { std::cout << "Executing task with priority: " << priority << std::endl; } }; int main() { Task task; // 传递成员函数:第一个参数是成员函数指针,第二个是对象实例 std::thread t(&Task::execute, &task, 5); t.join(); return 0; } ``` #### 关键注意事项: 1. **参数的生命周期** 使用 `detach()` 时要确保参数线程使用期间有效 2. **参数传递机制** `std::thread` *总是复制或移动参数*到线程内部存储[^3]: ```cpp // 错误:无法直接传递引用 std::thread t(worker, data); // 创建 data 的副本 // 正确:使用 std::ref 传递引用 std::thread t(worker, std::ref(data)); ``` 3. **参数转发** 使用完美转发保留参数类型: ```cpp template <typename Function, typename... Args> void startThread(Function&& f, Args&&... args) { std::thread t(std::forward<Function>(f), std::forward<Args>(args)...); t.detach(); } ``` #### 输出示例: ``` Processing item (1/3) Processing item (2/3) Processing item (3/3) New value: 20 Main thread value: 20 Vector sum: 15 Executing task with priority: 5 ```
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值