当前位置: 首页 > news >正文

std::thread的说明与示例

源于通义千问

在 C++ 中,std::thread 支持传递多种类型的函数作为线程入口点。你可以传递普通函数、类的成员函数、Lambda 表达式、函数对象(仿函数)等。以下是详细的说明和示例。


1. 传递普通函数

普通函数是最简单的用法。

示例
#include <iostream>
#include <thread>void myFunction(int x) {std::cout << "Thread ID: " << std::this_thread::get_id()<< ", Value: " << x << std::endl;
}int main() {// 创建线程并传递普通函数std::thread t(myFunction, 42);// 等待线程完成if (t.joinable()) {t.join();}return 0;
}
输出
Thread ID: 140735212345678, Value: 42

2. 传递类的成员函数

传递类的成员函数时,需要提供类实例的指针或引用。

示例
#include <iostream>
#include <thread>class MyClass {
public:void memberFunction(int x) {std::cout << "Thread ID: " << std::this_thread::get_id()<< ", Value: " << x << std::endl;}
};int main() {MyClass obj;// 创建线程并传递成员函数std::thread t(&MyClass::memberFunction, &obj, 42);// 等待线程完成if (t.joinable()) {t.join();}return 0;
}
输出
Thread ID: 140735212345678, Value: 42

3. 传递 Lambda 表达式

Lambda 表达式是一种简洁的方式,尤其适合定义临时逻辑。

示例
#include <iostream>
#include <thread>int main() {int value = 42;// 使用 Lambda 表达式创建线程std::thread t([value]() {std::cout << "Thread ID: " << std::this_thread::get_id()<< ", Value: " << value << std::endl;});// 等待线程完成if (t.joinable()) {t.join();}return 0;
}
输出
Thread ID: 140735212345678, Value: 42

4. 传递函数对象(仿函数)

函数对象是重载了 operator() 的类实例,可以像函数一样调用。

示例
#include <iostream>
#include <thread>class Functor {
public:void operator()(int x) const {std::cout << "Thread ID: " << std::this_thread::get_id()<< ", Value: " << x << std::endl;}
};int main() {Functor f;// 创建线程并传递函数对象std::thread t(f, 42);// 等待线程完成if (t.joinable()) {t.join();}return 0;
}
输出
Thread ID: 140735212345678, Value: 42

5. 传递绑定器(std::bind

使用 std::bind 可以将函数及其参数绑定在一起,生成一个可调用对象。

示例
#include <iostream>
#include <thread>
#include <functional>void myFunction(int x) {std::cout << "Thread ID: " << std::this_thread::get_id()<< ", Value: " << x << std::endl;
}int main() {// 使用 std::bind 绑定函数和参数auto boundFunction = std::bind(myFunction, 42);// 创建线程并传递绑定器std::thread t(boundFunction);// 等待线程完成if (t.joinable()) {t.join();}return 0;
}
输出
Thread ID: 140735212345678, Value: 42

6. 传递可调用对象(如 std::function

std::function 是一个通用的函数包装器,可以存储任何可调用对象。

示例
#include <iostream>
#include <thread>
#include <functional>void myFunction(int x) {std::cout << "Thread ID: " << std::this_thread::get_id()<< ", Value: " << x << std::endl;
}int main() {// 使用 std::function 存储可调用对象std::function<void()> callable = std::bind(myFunction, 42);// 创建线程并传递 std::functionstd::thread t(callable);// 等待线程完成if (t.joinable()) {t.join();}return 0;
}
输出
Thread ID: 140735212345678, Value: 42

总结

  • 普通函数:直接传递函数名。
  • 类的成员函数:需要提供类实例的指针或引用。
  • Lambda 表达式:适合定义临时逻辑。
  • 函数对象:重载 operator() 的类实例。
  • 绑定器(std::bind:用于绑定函数和参数。
  • std::function:通用的函数包装器。

多个线程、多个参数

在 C++ 中,如果需要通过 std::thread 传递多个参数给类的成员函数,可以直接将这些参数依次传递给线程构造函数。std::thread 会自动将这些参数转发给目标函数。

以下是详细的示例,展示如何传递多个参数给类的成员函数,并将其存储在 std::vector<std::thread> 中。


示例代码

#include <iostream>
#include <thread>
#include <vector>class MyClass {
public:// 成员函数,接受多个参数void memberFunction(int threadId, const std::string& message, double value) {std::cout << "Thread ID: " << std::this_thread::get_id()<< ", Thread Number: " << threadId<< ", Message: " << message<< ", Value: " << value << std::endl;}
};int main() {const int numThreads = 5; // 线程数量MyClass myClassInstance;  // 类实例std::vector<std::thread> threads; // 存储线程的容器// 创建多个线程并传递多个参数给类的成员函数for (int i = 0; i < numThreads; ++i) {threads.emplace_back(&MyClass::memberFunction, &myClassInstance,i, "Hello from thread", 3.14 + i);}// 等待所有线程完成for (auto& t : threads) {if (t.joinable()) {t.join();}}std::cout << "All threads finished." << std::endl;return 0;
}

代码解析

  1. 类定义

    • 定义了一个类 MyClass,其中包含一个成员函数 memberFunction,该函数接受三个参数:
      • int threadId:线程编号。
      • const std::string& message:字符串消息。
      • double value:浮点数值。
  2. 创建类实例

    • main 函数中,创建了 MyClass 的实例 myClassInstance
  3. 创建线程

    • 使用 std::vector<std::thread> 存储多个线程。
    • 使用 emplace_back 方法直接构造线程对象,并传递多个参数:
      threads.emplace_back(&MyClass::memberFunction, &myClassInstance,i, "Hello from thread", 3.14 + i);
      
      • 第一个参数是成员函数的指针:&MyClass::memberFunction
      • 第二个参数是类实例的地址:&myClassInstance
      • 后续参数是传递给成员函数的多个参数:i(当前线程编号)、"Hello from thread"(字符串)和 3.14 + i(浮点数)。
  4. 等待线程完成

    • 遍历 threads 容器,调用每个线程的 join() 方法,确保主线程等待所有子线程完成。

输出示例

运行程序后,输出可能如下(线程 ID 可能不同):

Thread ID: 140735212345678, Thread Number: 0, Message: Hello from thread, Value: 3.14
Thread ID: 140735212345789, Thread Number: 1, Message: Hello from thread, Value: 4.14
Thread ID: 140735212345890, Thread Number: 2, Message: Hello from thread, Value: 5.14
Thread ID: 140735212345991, Thread Number: 3, Message: Hello from thread, Value: 6.14
Thread ID: 140735212346092, Thread Number: 4, Message: Hello from thread, Value: 7.14
All threads finished.

注意事项

  1. 参数类型匹配

    • 确保传递给线程的参数类型与目标函数的参数类型匹配。例如,如果函数参数是引用类型(如 const std::string&),则可以传递临时对象或变量。
  2. 参数拷贝与移动

    • 如果传递的是复杂对象(如自定义类或容器),注意对象的拷贝或移动行为。可以通过 std::refstd::move 显式控制。
  3. 线程安全

    • 如果多个线程访问共享资源(如类的成员变量),需要使用互斥锁(std::mutex)或其他同步机制来确保线程安全。
  4. C++11 及以上版本

    • 上述代码需要 C++11 或更高版本支持。确保编译器支持 C++11,并使用适当的编译选项(例如 -std=c++11)。
http://www.xdnf.cn/news/620857.html

相关文章:

  • Linux中的文件描述符
  • 毕业论文格式(Word)
  • LINUX 524 rsync+inotify 调试(问题1:指定端口无法同步/已通过;问题2:rsync.log文件中时间不显示/已显示)
  • Linux--环境的搭建(云服务器)
  • 云原生安全:Linux命令行操作全解析
  • 自媒体运营新利器:账号矩阵+指纹浏览器,解锁流量密码
  • STM32中断优先级分组有哪几种?
  • 分享一套提高表达力的图书
  • 关于 Web 安全:4. 中间件 框架风险点分析
  • 【爬虫】爬bibi视频
  • LINQ性能优化终极指南
  • C++八股 —— 手撕shared_ptr
  • 我爱学算法之—— 二分查找(下)
  • 【案例篇】 实现简单SSM工程-后端
  • vue--ofd/pdf预览实现
  • mongodb语法$vlookup性能分析
  • 新能源产业破局之道:达索 3DE(PLM)系统重构数据管理与工程变更效率
  • 【Python 字典】基础到进阶的用法
  • 矩阵方程$Ax=b$的初步理解.
  • Windows 高分辨率屏幕适配指南:解决界面过小、模糊错位问题
  • 面向超大规模模型的提示词工程
  • UE5 图片导入,拖到UI上变色
  • 解决 cursor 中不能进入 conda 虚拟环境
  • PDF 转 JPG 图片小工具:CodeBuddy 助力解决转换痛点
  • 实现tdx-hs300-mcp
  • 【动态规划】简单多状态(二)
  • RIP 协议实验全记录:从配置到问题解决
  • HTTP基本概述
  • 在WPF程序中设置背景图片
  • ModbusRTU转profibusDP网关与RAC400控制器快速通讯