在 lambda 的捕获中传递参数以提升 asio post/dispatch 线程安全吗?
Does passing parameters in lambda's capture to boost asio post/dispatch thread safe?
我正在使用 lambda's capture
以便将参数传递给 boost::asio::io_context::post
回调。
它是线程安全的吗?
代码
#include <iostream>
#include "boost/asio.hpp"
#include <thread>
int main() {
boost::asio::io_service io_service;
boost::asio::io_service::work work(io_service);
std::thread t([&](){
io_service.run();
});
auto var = 1;
io_service.post([&io_service, var]() {
std::cout << "v: " << var << std::endl;
io_service.stop();
});
t.join();
return 0;
}
如您所见,我在 lambda's capture
中传递了 var
。
main thread
设置 var
的值,线程 t
读取它。
我没有使用任何 memory ordering
,例如,将 var
设置为 1
之后的 std::memory_order_release
,以及读取 var
值之前的 std::memory_order_acquire
。更重要的是,我不认为我可以 - 因为变量 var
按值传递给 lambda
.
这样做安全吗?
如果不行,应该怎么做?
它是线程安全的。
闭包对象在 var
创建并初始化后由主线程创建(复制 var
值)。
接下来,闭包对象作为参数传递给 post
方法,该方法将此函数对象和 returns 立即排队,而不调用仿函数。 Functor 在 post
和 t.join
调用之间被调用 - post
保证它。
所以你的代码必须是线程安全的。
您需要一些同步方法(例如,使用 mutex
+lock_guard
)
如果 var
是通过引用 [1] 和 var
[2] 上的一些写入操作传递的
在 post
和 t.join
调用之间执行:
auto var = 1;
io_service.post([&io_service, &var]() { // [1] takes by reference
std::cout << "v: " << var << std::endl; // lock mutex for printing
io_service.stop();
});
var = 10; // [2] , lock mutex for writing
// synchronization must be added because between post and t.join calls,
// reading and writing operations are executed
t.join();
在这种情况下,您必须保护 var
。
我正在使用 lambda's capture
以便将参数传递给 boost::asio::io_context::post
回调。
它是线程安全的吗?
代码
#include <iostream>
#include "boost/asio.hpp"
#include <thread>
int main() {
boost::asio::io_service io_service;
boost::asio::io_service::work work(io_service);
std::thread t([&](){
io_service.run();
});
auto var = 1;
io_service.post([&io_service, var]() {
std::cout << "v: " << var << std::endl;
io_service.stop();
});
t.join();
return 0;
}
如您所见,我在 lambda's capture
中传递了 var
。
main thread
设置 var
的值,线程 t
读取它。
我没有使用任何 memory ordering
,例如,将 var
设置为 1
之后的 std::memory_order_release
,以及读取 var
值之前的 std::memory_order_acquire
。更重要的是,我不认为我可以 - 因为变量 var
按值传递给 lambda
.
这样做安全吗?
如果不行,应该怎么做?
它是线程安全的。
闭包对象在 var
创建并初始化后由主线程创建(复制 var
值)。
接下来,闭包对象作为参数传递给 post
方法,该方法将此函数对象和 returns 立即排队,而不调用仿函数。 Functor 在 post
和 t.join
调用之间被调用 - post
保证它。
所以你的代码必须是线程安全的。
您需要一些同步方法(例如,使用 mutex
+lock_guard
)
如果 var
是通过引用 [1] 和 var
[2] 上的一些写入操作传递的
在 post
和 t.join
调用之间执行:
auto var = 1;
io_service.post([&io_service, &var]() { // [1] takes by reference
std::cout << "v: " << var << std::endl; // lock mutex for printing
io_service.stop();
});
var = 10; // [2] , lock mutex for writing
// synchronization must be added because between post and t.join calls,
// reading and writing operations are executed
t.join();
在这种情况下,您必须保护 var
。