我刚刚开始学习 C++ 中的多线程...t1
之间有区别吗?和 t2
?
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mutexCout;
//prints the value of x, and then increments it
//param: int value to display and increment
void foo (int& x)
{
std::lock_guard<std::mutex> guard_(mutexCout);
std::cout << "x is " << x << "\n";
++x;
}
//testing different ways to call a function with reference
int main()
{
int x = 5;
//is t1 different from t2???
std::thread t1 ([&] {foo(x)};
std::thread t2 (foo, std::ref(x));
{
std::lock_guard<std::mutex> guard_(mutexCout);
std::cout << "x is " << x << "\n";
}
//added after posting the question
t1.join();
t2.join();
return 0;
}
最佳答案
我假设您通过调用加入来修复它。
使用 [&]
捕获超过当前范围或在不同线程中运行的 lambda 通常是一个坏主意:在两种情况下,您应该有足够少的共享状态,明确说明您共享的内容,如 [&x]
这不是一个严重的开销问题,并且可以防止您由于看似无害的拼写错误或命名错误而以危险的方式意外共享错误数据。
通常,使用原始 C++ std
应用程序中的线程 API 仅在应用程序小而简单且线程有限时才有用。过了这一点,您将需要线程池、延续、信号等。C++ 线程原语足以编写这些,但它们不提供这些。
我发现,当我编写自己的包装器时,期望调用者传入一个空值可调用对象(或只包含它期望线程框架提供的参数的对象)比做 std
的事情要理智得多。做了你也可以传递参数的地方。使用 c++14,这变得更加可行。对 lambda 语法的补充,允许移动参数和计算绑定(bind)。
因此,在“真实”代码中,我的代码如下所示:
my_future<void> r = some_thread_pool.add_task([&x] {foo(x)});
关于multithreading - 在 C++ 多线程应用程序中,我应该传递 lambda 还是带参数的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47874222/