0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Tokio中hang死所有worker的方法

jf_wN0SrCdH 来源:Rust语言中文社区 2023-02-03 16:26 次阅读

Tokio[1]的 task (一个 Future ) 里如果使用了阻塞调用,例如std::Mutex,会阻塞当前的 tokio-worker 线程,这个 worker 无法再执行其他 task。所以代码里如果不可避免的有(少量的)阻塞调用,就要为 runtime 启动更多的 worker 线程,保证存在没被阻塞的 worker 来执行待调度的 task,以避免整个 tokio runtime 完全 hang 住(有 task 但没 worker 运行它)。

但现实是,就算 worker 再多,tokio 也可能造成永久性的阻塞。

原因是 tokio 里的待执行 task 不是简单的放到一个 queue 里,除了 runtime 内共享的,可被每个 worker 消费的run_queue[2],每个 worker 还有一个自己的lifo_slot[3],只存储一个最后被放入的 task (目的是减小调度延迟)。lifo_slot只由它所属的 worker 使用,里面存储的 task 不能被其他 worker 执行。由于这个结构,构造 hang 住的方法是如图所示:

  • •Future f1 被 runtime-1 执行, 持有一个 async 的锁m后,返回了Pending,这时它被调度到 worker-1 本地的lifo_slot

  • •Future f2 在 runtime-1 执行后返回Pending,被放入共享队列run_queue

  • •Future f3 在 runtime-1 中执行, 它将一个任务f4交给其他的 runtime 去完成(例如为了隔离网络IO和本地磁盘IO),使用block_on(f4)[4]的方式,等待执行结果返回。

  • • f4 中也需要锁m,等待。

这时,f2 在共享队列run_queue中,可以被执行,但是 f1 在 worker-1 本地的lifo_slot里,只能由 worker-1 调度,但 worker-1 当前阻塞在 f3。于是等待关系形成了一个环:f4 → m(f1) → f3 → f4,hang 死任务达成。

cc721fae-a397-11ed-bfe3-dac502259ad0.png

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 存储
    +关注

    关注

    13

    文章

    4219

    浏览量

    85565
  • 线程
    +关注

    关注

    0

    文章

    503

    浏览量

    19634
  • Worker
    +关注

    关注

    0

    文章

    8

    浏览量

    6449
  • Tokio
    +关注

    关注

    0

    文章

    12

    浏览量

    50

原文标题:Tokio 中 hang 死所有 worker 的方法

文章出处:【微信号:Rust语言中文社区,微信公众号:Rust语言中文社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    什么是Tokio模块 Channel?

    的一个重要组成部分,它可以用于在异步任务之间传递数据。在本教程,我们将介绍 Rust 语言中的 Tokio 模块 channel,并提供几个示例,以帮助您更好地理解它的使用方法。 什么是 T
    的头像 发表于 09-19 15:57 899次阅读

    鸿蒙原生应用开发-ArkTS语言基础类库多线程TaskPool和Worker的对比(三)

    的路径(scriptURL),Worker文件存放位置默认路径为Worker文件所在目录与pages目录属于同级。 四、Stage模型 构造函数的scriptURL示例如下: // 导入模块
    发表于 03-27 16:26

    面向对象嵌入式实时操作系统Worker1.0

    Worker1.0继承图1 Worker1.0主要类的简介3 Worker1.0 API4 Worker1.0移植9 Worker1.0例程
    发表于 04-29 18:01 39次下载
    面向对象嵌入式实时操作系统<b class='flag-5'>Worker</b>1.0

    normal worker_pool详细的创建过程代码分析

    默认 work 是在 normal worker_pool 处理的。系统的规划是每个 CPU 创建两个 normal worker_pool:一个 normal 优先级 (nice=0)、一个高
    的头像 发表于 04-08 14:35 7232次阅读
    normal <b class='flag-5'>worker</b>_pool详细的创建过程代码分析

    WasmEdge增加了Tokio支持

    看:https://wasmer.io/posts/wasmer-takes-webassembly-libraries-manistream-with-wai WasmEdge增加了Tokio 支持
    的头像 发表于 12-05 11:55 789次阅读

    PCB上的铜对电路性能的影响

    在PCB的制造和设计过程,可能会出现一种叫做"铜"的问题。本文将解析铜在PCB上的含义、成因、对电路性能的影响以及解决方法
    的头像 发表于 06-05 14:16 1132次阅读
    PCB上的<b class='flag-5'>死</b>铜对电路性能的影响

    Tokio 模块的优雅停机机制

    在进行高并发、网络编程时,优雅停机是一个非常重要的问题。在 Rust 语言中,Tokio 是一个非常流行的异步编程框架,它提供了一些优雅停机的机制,本文将围绕 Tokio 模块的优雅停机进行详细
    的头像 发表于 09-19 15:26 561次阅读

    如何使用Tokio 和 Tracing模块构建异步的网络应用程序

    ,并在调试和故障排除时提供有用的信息。 在本教程,我们将介绍如何使用 Tokio 和 Tracing 模块来构建一个异步的网络应用程序,并使用 Tracing 来记录应用程序的行为和性能。我们将从安装和配置开始,然后介绍如何使用 To
    的头像 发表于 09-19 15:29 612次阅读

    如何使用 Tokio 模块的Channel

    便地进行消息传递和数据共享。 在本教程是 Channel 的下篇,我们将介绍如何使用 Tokio 模块的 Channel,包括如何使用异步 Channel 和如何使用标准库的同步 Channel 来扩展
    的头像 发表于 09-19 15:38 614次阅读

    tokio模块channel的使用场景和优缺点

    Rust 语言的 tokio 模块提供了一种高效的异步编程方式,其中的 channel 模块是其核心组件之一。本教程将介绍 tokio 模块 channel 的除了上文提到的 mspc
    的头像 发表于 09-19 15:54 714次阅读

    Tokio 的基本用法

    Tokio 篇将由浅入深的从基础到实战,以一个完整的 Rust 语言子系列讲述网络编程。 为什么要使用 Tokio? 在 Rust ,使用异步编程可以提高程序的性能和响应速度,但是异步编程往往需要编写
    的头像 发表于 09-19 16:05 754次阅读

    Channel模块的使用方法示例

    教程,我们将介绍 Rust 语言中的 Tokio 模块 channel,并提供几个示例,以帮助您更好地理解它的使用方法。 什么是 Tokio 模块 Channel?
    的头像 发表于 09-20 11:47 974次阅读

    Object类所有方法

    ,也就是说任何类都直接或间接继承此类,Object 类能访问的方法所有类中都可以调用,下面我们会分别介绍Object 类所有方法
    的头像 发表于 10-13 11:50 483次阅读
    Object类<b class='flag-5'>中</b>的<b class='flag-5'>所有方法</b>

    鸿蒙APP开发:【ArkTS类库多线程】TaskPool和Worker的对比(2)

    创建Worker的线程称为宿主线程(不一定是主线程,工作线程也支持创建Worker子线程),Worker自身的线程称为Worker子线程(或Actor线程、工作线程)。每个
    的头像 发表于 03-27 15:44 498次阅读
    鸿蒙APP开发:【ArkTS类库多线程】TaskPool和<b class='flag-5'>Worker</b>的对比(2)

    鸿蒙语言基础类库:ohos.worker 启动一个Worker

    Worker是与主线程并行的独立线程。创建Worker的线程称之为宿主线程,Worker自身的线程称之为Worker线程。创建Worker
    的头像 发表于 07-11 17:03 367次阅读
    鸿蒙语言基础类库:ohos.<b class='flag-5'>worker</b> 启动一个<b class='flag-5'>Worker</b>