Libuv多路事件循环(Multiple event loops)

Libuv多路事件循环(Multiple event loops)

文章目录

你也可以在同一个线程中使用多路事件循环, 但意义并不大, 因为调用其中某一个事件循环的 uv_run 会使得程序阻塞, 其他事件循环不能同时运行. 不过也可以小心地通过多次调用 uv_run_once() 来完成一些有趣的工作.

多路事件循环的形式(Modality)

你可以在你的程序中按照相对标准方式使用多路事件循环, 即第二个事件循环先暂停第一个事件循环, 直到发生了动作(用户按下了 Return(Enter) 键, 或者发生了新的事件等).

各线程拥有自己的事件循环(One loop per thread)

One loop per thread 才是多路事件循环的’标准模型’, 它和我们在 进程 一章中介绍的产生多个进程方式并无太大区别.

使用两个事件循环来同步(sing two loops for synchronization)

也有一些比较特殊的应用场景需要两个事件循环来进行同步(而不是使用条件变量), 在 node-taglib 库中我就使用了这种同步机制. 具体的应用场景如下:

  1. 主线程 main thread 通过 uv_queue_work 在工作线程中调用一个阻塞函数.
  2. 工作线程 worker thread 调用一个自定义函数, 并且自定义函数必须在主线程中运行.
  3. 工作线程一直等待, 直到函数返回.

如果使用条件变量来实现:

  1. 工作线程并不直接调用自定义函数, 而是创建一个 uv_async_t 句柄, 然后由该句柄的回调函数调用自定义函数.
  2. 初始化条件变量.
  3. 使用 uv_async_send() 获得主线程(运行事件循环的线程)并由主线程调用该函数.
  4. 等待条件变量的通知.
  5. 回调函数调用自定义函数, 并向条件变量发送通知, 使得工作线程得以继续下去.

而事件循环的实现方式为:

  1. 在工作线程中创建一个新的事件循环.
  2. uv_async_t 与事件循环相关联.
  3. 将该句柄通过 uv_async_t 结构 data 字段传递给主线程.
  4. uv_run() 运行事件循环, 此时程序会阻塞, 因为异步句柄自增了它的 refcount.
  5. 主线程的回调函数再调用自定义函数,然后调用 uv_async_send 向事件循环的异步句柄发送消息.
  6. 异步句柄的回调函数关闭自己, 然后事件循环的引用计数减为 0, uv_run 返回, 工作线程得以继续下去.
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值