我想知道在以下方面构建std::thread
的各种方式之间是否存在很大差异。
#include <iostream>
#include <thread>
void test ()
{
int x = 5;
auto example1 = std::thread([x] () {
std::cout << x;
});
auto example2 = std::thread([] (int x) {
std::cout << x;
}, x);
}
根据http://en.cppreference.com/w/cpp/thread/thread/thread,在example2
的情况下,我将x
复制/移动到#34;到线程可访问的存储&#34;。我不知道该怎么做。
此存储是否有助于防范false sharing或类似内容?
或者是将这些参数直接传递到std::thread
构造函数中以使调用非lambda函数更简单的主要原因?例如,要避免example3
使用example4
:
#include <iostream>
#include <thread>
void foo (int x);
void test ()
{
int x = 5;
auto example3 = std::thread([x] () {
foo(x);
});
auto example4 = std::thread(foo, x);
}
答案 0 :(得分:3)
example1
和example2
之间没有真正的区别。 thread( Function&& f, Args&&... args );
构造函数的cppreference描述稍微偏离 - DECAY_COPY
,正如标准所调用的那样,是针对仿函数f
和参数args...
执行的。
换句话说,创建的线程有自己的仿函数副本(包括lambda捕获的任何东西)和你传递的任何参数;这使您更难以编写数据争用或导致悬挂指针和引用的未定义行为。毕竟,lambda表达式创建了一个临时函子,它在下一个;
被销毁。如果thread
的构造函数没有复制,那么你就会陷入困境。
无论你选择传递lambda中的所有内容,还是使用bind
- 分别传递参数的方式,主要是风格问题。有时可能很难使用类似bind
的版本,例如,如果要调用的函数被重载或是函数模板。其他时候你可能无法捕获lambda中的某些东西,特别是在C ++之前14。