C++线程创建:直接传函数与Lambda包装函数是否等价?
两种std::thread创建方式是否等价?
#include <iostream> #include <thread> class MyClass { public: MyClass(int val) : val_(val) {} int val_{0}; }; void threadFunction(MyClass myObj) { // do something ... } int main() { MyClass obj(42); std::thread t1(threadFunction, obj); std::thread t2([=]() { threadFunction(obj); }); t1.join(); t2.join(); return 0; }
在线程t1中,直接将threadFunction和obj作为参数传入std::thread构造函数;在线程t2中,通过按值捕获obj的Lambda表达式调用threadFunction。请问这两种线程创建方式是否等价?
在你给出的代码场景下,两种方式的最终执行效果是等价的,但背后的实现细节存在细微差异:
- 拷贝路径与时机:
- 对于
t1:std::thread构造时会在主线程中将obj拷贝到线程内部存储;子线程启动后,再将这份内部存储的拷贝复制给threadFunction的形参myObj,总共发生两次拷贝。 - 对于
t2:创建Lambda表达式时会在主线程中将obj拷贝到Lambda闭包中;子线程启动后,从闭包中取出副本再复制给threadFunction的形参myObj,同样是两次拷贝。
- 对于
两者最终都会让threadFunction接收到原始obj的副本,因此从业务逻辑的执行结果来看是完全一致的。
如果MyClass的拷贝构造函数带有副作用(比如打印日志、修改全局状态),你会发现两次拷贝的触发上下文略有不同,但这属于底层实现细节,不会影响核心逻辑的等价性。
内容的提问来源于stack exchange,提问作者Mathieu
相关产品推荐
相关产品推荐

