繁体   English   中英

将const引用传递给临时/匿名lambda到std :: thread构造函数是否安全?

[英]Is it safe to pass const reference to temporary/annonymous lambda into std::thread constructor?

继这个问题之后: 可以通过参考传递一段时间吗?

我有一个固定的代码片段:

// global variable
std::thread worker_thread;

// Template function
template <typename Functor>
void start_work(const Functor &worker_fn)  // lambda passed by const ref
{
    worker_thread = std::thread([&](){
        worker_fn();
    });
}

这被称为:

void do_work(int value)
{
    printf("Hello from worker\r\n");
}

int main()
{
    // This lambda is a temporary variable...
    start_work([](int value){ do_work(value) });
}

这似乎有效,但我担心将临时lambda传递给线程构造函数,因为线程将运行,但函数start_work()将返回并且temp-lambda将超出范围。

但是我正在查看定义的std :: thread构造函数:

thread()noexcept; (1)(自C ++ 11以来)

thread(thread && other)noexcept; (2)(自C ++ 11起)

template <class Function,class ... Args> explicit thread(Function && f,Args && ... args); (3)(自C ++ 11起)

thread(const thread&)= delete; (4)(自C ++ 11以来)

所以我假设构造函数3被调用:

template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );

我很难理解这里写的是什么,但看起来它会尝试移动lambda && ,我认为这对于临时变量是好的。

那么我在我的代码片段中做了什么危险(即ref超出范围)或更正(即temp被移动,一切都很好)? 还是两个?

另一种方法是传递我的价值(制作副本),在这种情况下无论如何都不是那么糟糕。

临时的确移动,但它是“内部”一个,给个说法std::thread

该临时文件包含对“外部”临时文件的引用, start_work的参数,以及在start_work返回后其生命周期结束的start_work

因此,您的“内部”lambda对象包含对在执行期间可能存在或可能不存在的对象的引用,这是非常不安全的。

lambda是C ++中的匿名struct 如果我们要将片段翻译成没有lambdas的等效片段,它就会变成

template <typename Functor>
void start_work(const Functor &worker_fn)
{
    struct lambda {
        const Functor& worker_fn;
        auto operator()() const { worker_fn(); }
    };
    worker_thread = std::thread(lambda{worker_fn});
}

lambda有一个非基于堆栈的const引用作为成员,一旦start_work返回就会start_work ,无论lambda对象本身是否被复制。

暂无
暂无

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

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