c++11引入的多线程非常方便,结合lambda表达式可以快速将单线程程序改为多线程。
c++使用引用传参是一个常用的技巧,可以减少数据拷贝,有时也用来传递返回值。
但是在多线程函数中,使用引用作为参数要注意引用值是否会改变。
在下面的示例程序中,for循环中的a传递给的每个线程都是同一个地址,当func函数执行慢于for循环时,该值即会发生改变。
由于func拿到参数一般都会立即使用,很可能会出现多数情况没有bug,只有偶尔才触发bug的隐秘情况。
传拷贝就不会出现这样的问题;
当没有使用多线程时,由于程序顺序执行,func执行完毕后程序for才会迭代,也不会出现这样的问题。
#include <cstdio>#include <vector>#include <thread>
void func(const int& a){ std::this_thread::sleep_for(std::chrono::milliseconds(5)); printf("value is %d, address is %X\n", a, &a);}
int main(){ std::vector<std::thread> threads; for(inti=1;i<=5;i++) { int a = i * 10; std::this_thread::sleep_for(std::chrono::milliseconds(1)); //auto th = std::thread([&](){func(a);}); auto th = std::thread([](int&b){func(b);}, std::ref(a)); //th.join(); threads.emplace_back(std::move(th)); } for(auto& th: threads) th.join(); return 0;}