如何将数据传递给将在不同线程中运行的 C++0x lambda 函数?

发布于 2024-09-03 08:12:33 字数 1612 浏览 1 评论 0原文

重要更新:显然,当我问这个问题时,我得出了错误的结论。感谢您的回复,我发现 lambda 函数 [=]() 在多线程场景中工作得很好。我很抱歉提出这个令人困惑的问题。请投票结束,因为这不是问题。


在我们公司,我们编写了一个库函数来在单独的线程中异步调用函数。它使用继承和模板魔法的组合来工作。客户端代码如下所示:

DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, &DemoThread::SomeFunction, stringToPassByValue);

自从引入 lambda 函数以来,我想将它与 lambda 函数结合使用。我想编写以下客户端代码:

DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, [=]()
{
    const std::string someCopy = stringToPassByValue;
});

更新:与我在提出这个问题时首先相信的相反,此代码工作正常。

<罢工> 现在,在 Visual C++ 2010 中,此代码不起作用。发生的情况是 stringToPassByValue 未被复制。相反,“按值捕获”功能通过引用传递数据。结果是,如果该函数在 stringToPassByValue 超出范围后执行,则应用程序会崩溃,因为它的析构函数已经被调用。

所以我想知道:是否可以通过数据作为 lambda 函数的副本

注意:一种可能的解决方案是修改我们的框架以传递 lambda 参数声明列表中的数据,如下所示:

DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, [=](const std::string stringPassedByValue)
{
    const std::string someCopy = stringPassedByValue;
}
, stringToPassByValue);

但是,此解决方案非常冗长,以至于我们原始的函数指针解决方案既短又简单阅读。

更新AsyncCall 的完整实现太大,无法在此处发布。简而言之,AsyncCall 模板函数会实例化一个包含 lambda 函数的模板类。此类派生自包含虚拟 Execute() 函数的基类,并且在调用 AsyncCall() 时,函数调用类将被放入调用队列中。然后,另一个线程通过调用虚拟 Execute() 函数来执行排队的调用,该函数以多态方式分派到模板类,然后模板类执行 lambda 函数。

Important update: Apparently I drew the wrong conclusion when I asked this question. Thanks to the responses I found out the lambda function [=]() does work fine in a multithreaded scenario. My apologies for posing this confusing question. Please vote to close, as it was a non-issue.


In our company we've written a library function to call a function asynchronously in a separate thread. It works using a combination of inheritance and template magic. The client code looks as follows:

DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, &DemoThread::SomeFunction, stringToPassByValue);

Since the introduction of lambda functions I'd like to use it in combination with lambda functions. I'd like to write the following client code:

DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, [=]()
{
    const std::string someCopy = stringToPassByValue;
});

Update: contrary to what I first believed when asking this question, this code works fine.


Now, with the Visual C++ 2010 this code doesn't work. What happens is that the stringToPassByValue is not copied. Instead the "capture by value" feature passes the data by reference. The result is that if the function is executed after stringToPassByValue has gone out of scope, the application crashes as its destructor is called already.

So I wonder: is it possible to pass data to a lambda function as a copy?

Note: One possible solution would be to modify our framework to pass the data in the lambda parameter declaration list, as follows:

DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, [=](const std::string stringPassedByValue)
{
    const std::string someCopy = stringPassedByValue;
}
, stringToPassByValue);

However, this solution is so verbose that our original function pointer solution is both shorter and easier to read.

Update: The full implementation of AsyncCall is too big to post here. In short, what happens is that the AsyncCall template function instantiates a template class holding the lambda function. This class is derived from a base class that contains a virtual Execute() function, and upon an AsyncCall() call, the function call class is put on a call queue. A different thread then executes the queued calls by calling the virtual Execute() function, which is polymorphically dispatched to the template class which then executes the lambda function.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文