【问题标题】:How to use libuv async handles in a thread-safe manner?如何以线程安全的方式使用 libuv 异步句柄?
【发布时间】:2019-02-21 09:17:17
【问题描述】:

uv_async_send 是线程安全的,但uv_async_init 不是。如果我使用uv_async_init在循环的线程中创建一个异步句柄,我可能会多次调用uv_async_send,但它的回调只会被调用一次。我需要调用回调的次数与调用 uv_async_send 的次数相同。

但是当我为另一个线程中的每个回调创建一个异步句柄时,它是不安全的。那么,如何以线程安全的方式使用 libuv 异步句柄?

【问题讨论】:

    标签: c thread-safety libuv


    【解决方案1】:
    1. 在循环的线程中创建一个异步句柄。
    2. 实现线程安全队列。 (libuv 没有在其 API 中公开一个,但它确实公开了对创建一个有用的原语,例如uv_mutex_t
    3. 其他线程将一个项目放入线程安全调用中,然后立即调用uv_async_send
    4. 异步回调从队列中移除所有待处理的项目并对其进行处理。

    【讨论】:

      【解决方案2】:

      uv_async_init 不是线程安全的……当我为其他线程中的每个回调创建异步句柄时不安全……我可以在循环的线程中创建异步句柄

      您似乎误解了术语线程安全。这并不意味着您不能从循环线程以外的线程调用uv_async_init()。这只是意味着您不能从多个线程并行调用它(没有互锁)。

      【讨论】:

      • 你错了,uv_async_init函数需要libuv的参数循环句柄(添加事件到循环),什么总是在循环线程中运行。那么,可以从其他线程调用这个函数吗?
      • 我只是试图阐明线程安全的一般含义。我不明白您所说的“libuv 的循环句柄......什么总是在循环线程中运行”- handle 如何running
      • 对不起,我没有解释清楚。我的意思是,在 libuv 循环的线程中,它操作循环的句柄 for run && add && close libuv 的事件。uv_async_init func 在循环线程中添加一个异步事件loop 的 hanlde。所以,在 loop 的线程外调用 uv_async_init 是不安全的。
      • 我同意这个答案是不正确的。 uv_async_init 修改了非线程安全的 uv_loop_t 数据结构,因此从主循环线程以外的任何线程(即拥有该特定 uv_loop_t 的线程)调用它都是不安全的。相比之下,uv_async_send 被明确记录为可以安全地从其他线程调用。这就是“uv_async_init 不是线程安全的”的意思。 Saghul(libuv 开发人员之一)确认here
      猜你喜欢
      • 1970-01-01
      • 2021-08-19
      • 2012-11-30
      • 2021-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多