当前位置: 首页 > news >正文

Gevent和Subprocess问题

Gevent和Subprocess问题

1、复现

在main文件中调用gevent、并做了monkey pathch, 然后再调用subprocess.Popen(),出现一直卡住的问题

  • Python 标准库里的很多 IO(网络 socket、ssl、time.sleep 等)都是 阻塞的
    • 调用 socket.recv() 会阻塞整个线程,其他 greenlet 无法运行。
  • 为了让这些阻塞调用 在等待时让出控制权,gevent 需要“接管”标准库里的阻塞函数 → 这就是 monkey patch
from gevent import monkey
monkey.patch_all()import subprocessp = subprocess.Popen("echo 111", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)p.wait()

2、原因

monkey.patch_all() 会对 Python 的标准库做打猴子补丁,其中包括 subprocess。而被打过补丁的 subprocess 在某些情况下(尤其是涉及到 Popencommunicatewait 或交互式命令)会出现 阻塞/卡住 的情况

  • subprocess 被 gevent 补丁后不完全兼容
    gevent 会用协程友好的 IO 替换底层调用,但 subprocess 的管道和底层 select/poll 行为会变得不可预期。
  • 所有 Popencommunicatewait 都是标准阻塞版本,不会和 gevent 的事件循环配合

3、解决方法

以下是两种解决办法, 确认是否需要协程化的子进程

  • 如果只是跑系统命令、不需要协程化,建议用 原生 subprocess,用方法1
  • 如果需要和 gevent 事件循环兼容,再考虑 gevent.subprocess, 用方法2

方法1:不要 monkey patch subprocess
在调用 monkey.patch_all() 时,可以显式排除:

from gevent import monkey
monkey.patch_all(subprocess=False)

 

方法2:使用 gevent.subprocess 代替
如果你确实想在 gevent 下用子进程,可以用:

from gevent import subprocess
p = subprocess.Popen(["cmd", "/c", "echo hello"], stdout=subprocess.PIPE)
out, err = p.communicate()
print(out.decode())

这个是 gevent 提供的封装,适配了它的事件循环。

http://www.jsqmd.com/news/1460/

相关文章:

  • WPF ListBox loaded 76.6M items with imagesource
  • Ansible自动化运维实战 - 详解
  • 建筑行业能源管理破局:MyEMS 打造商业楼宇 “能耗可视化 + 智能调控” 方案
  • 【数据结构】双向链表 - 指南
  • 告别“能源糊涂账”:MyEMS如何帮企业把能耗数据“算明白、用到位”
  • 完整教程:ElasticSearch倒排索引原理
  • Windows 离线环境下使用 VS Code 连接容器 Python 环境完整指南(亲测可用)
  • Macos 安装kali报错
  • 负载排查和分析二
  • 负载排查和分析三
  • 完整教程:线程、进程、协程
  • CF913G Power Substring
  • 深入解析:老树发新芽:六西格玛培训为石油机械制造注入持久活力
  • YC大佬分享的 10 个 vibe coding技巧,看完收获巨大
  • ES集群部署-EFK架构实战 - 实践
  • 《BOE解忧实验室》第四季圆满收官 以科技重塑文化生活新范式
  • 洛谷P2261 [CQOI2007] 余数求和
  • 负载排查和优化
  • 挑战骑行距离新记录:46公里
  • arc206 总结
  • 科研必读|提升酿酒酵母表达蛋白产量的关键技术
  • 【RK3576】【Android14】如何在Android14下单独编译kernel-6.1? - 详解
  • 完整教程:栈与队列的实现方式与应用解惑
  • 完整教程:uniapp、devceo华为鸿蒙运行模拟器报错:未开启Hyper-V
  • 深入解析:08_多层感知机
  • 9.8C++作业 - 实践
  • (一)React面试(虚拟DOM/类组件) - 详解
  • 浏览器访问页面卡顿刷新页面方法
  • 完整教程:散斑深度相机原理
  • k8s Understanding Kubernetes Security Components