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;
}