【发布时间】:2018-04-10 15:33:30
【问题描述】:
我想知道需要采取哪些预防措施才能从 C++ 中的多个线程安全地将回调添加到 libuv 事件循环。
更多详情
我想修改一些多线程 C++11 代码以使用 libuv 的网络通信 API。我不想在每次需要网络通信时都创建一个新的 libuv 事件循环(因为那样会耗尽资源)。所以我在一个单独的线程中创建了一个libuv 循环(我通过注册一个“keep-alive”计时器来防止循环关闭)。此事件循环当前使用singleton 传递给其他线程。然后在循环运行时注册回调(来自其他线程)。
我担心注册新回调时并发访问libuv 事件循环:当调用uv_tcp_init 时,循环被显式传递(而是指向循环的指针);当调用uv_tcp_connect 时,没有明确提及循环,但指向它的指针存储在传递的uv_tcp_t 结构中。我还没有检查上述任何函数是否真的修改了循环,但我的直觉是其中至少有一个必须这样做(否则,libuv 无法跟踪活动句柄)。
我的第一个想法是在用于访问事件循环的单例中添加mutex属性,并在调用上述任何函数时使用它来防止并发访问事件循环:
EventLoop & loop = EventLoop::get(); // Access the singleton
{
std::lock_guard<std::mutex> lock(loop.mutex_attribute);
// Register callbacks, etc
}
但是,这并不能保护事件循环免受我的线程(成功获取锁)和一些libuv 内部函数(或由libuv 触发的注册回调)之间的并发访问,因为后者不知道我使用单例来保护访问。
我应该担心所说的并发访问吗?我可以采取哪些措施来降低风险?
【问题讨论】:
标签: c++ multithreading c++11 libuv