简体   繁体   English

构造一个std :: thread via(Args && ...)

[英]Constructing an std::thread via (Args&&…)

I was wondering if there is much of a difference between various ways of constructing an std::thread in the following ways. 我想知道在以下方面构建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);
}

According to http://en.cppreference.com/w/cpp/thread/thread/thread , with the example2 case, I get x copied/moved "to thread-accessible storage". 根据http://en.cppreference.com/w/cpp/thread/thread/thread ,对于example2案例,我将x复制/移动到“线程可访问存储”。 I'm not sure what to make of this. 我不知道该怎么做。

Does this storage help protect against false sharing or something like that? 这个存储有助于防止虚假共享或类似的东西吗?

Or is the main reason for passing in these arguments directly into the std::thread constructor there to make calling non-lambda functions a tad simpler? 或者是将这些参数直接传递给std::thread构造函数以使调用非lambda函数更简单的主要原因? For example, to avoid the boilerplate given by example3 by using example4 : 例如,要使用example4来避免example3给出的样板:

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

There's no real difference between example1 and example2 . example1example2之间没有真正的区别。 The cppreference description of the thread( Function&& f, Args&&... args ); thread( Function&& f, Args&&... args );的cppreference描述thread( Function&& f, Args&&... args ); constructor is slightly off - DECAY_COPY , as the standard calls it, is performed for both the functor f and the arguments args... . 构造函数稍微关闭 - DECAY_COPY ,正如标准所调用的那样,是为了函数f和参数args...

In other words, the created thread has its own copy of the functor (which includes anything captured by the lambda) and any arguments you passed; 换句话说,创建的线程有自己的仿函数副本(包括lambda捕获的任何东西)和你传递的任何参数; this makes it harder for you to write a data race or cause undefined behavior with dangling pointers and references. 这使您更难以编写数据争用或导致悬挂指针和引用的未定义行为。 After all, the lambda expression creates a temporary functor that is destroyed at the next ; 毕竟,lambda表达式创建了一个临时的函子,在下一个被破坏; . If thread 's constructor didn't make a copy, you'd be in deep trouble. 如果thread的构造函数没有复制,你就会陷入困境。

Whether you choose to pass everything in a lambda, or use the bind -like way of passing the arguments separately, is mostly a matter of style. 无论你选择传递lambda中的所有内容,还是使用类似bind的方式分别传递参数,主要是风格问题。 Sometimes it can be difficult to use the bind -like version, for instance if the function you want to call is overloaded or is a function template. 有时,使用类似bind的版本可能很困难,例如,如果要调用的函数被重载或者是函数模板。 Other times you may not be able to capture something in a lambda, especially pre-C++14. 其他时候你可能无法捕获lambda中的某些东西,特别是在C ++之前14。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM