当前位置: 首页 > 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.gsyq.cn/news/9495.html

相关文章:

  • WPF ListBox loaded 76.6M items with imagesource
  • 【数据结构】双向链表 - 指南
  • 告别“能源糊涂账”:MyEMS如何帮企业把能耗数据“算明白、用到位”
  • 完整教程:ElasticSearch倒排索引原理
  • 负载排查和分析三
  • 完整教程:线程、进程、协程
  • CF913G Power Substring
  • ES集群部署-EFK架构实战 - 实践
  • 《BOE解忧实验室》第四季圆满收官 以科技重塑文化生活新范式
  • 洛谷P2261 [CQOI2007] 余数求和
  • 完整教程:uniapp、devceo华为鸿蒙运行模拟器报错:未开启Hyper-V
  • 深入解析:08_多层感知机
  • (一)React面试(虚拟DOM/类组件) - 详解
  • 浏览器访问页面卡顿刷新页面方法
  • 完整教程:散斑深度相机原理
  • k8s Understanding Kubernetes Security Components
  • G1垃圾回收过程
  • Trellix自动化大规模修复开源漏洞,已修补超6万个项目
  • 人形机器人 —— 电机控制的三种模式 —— 力矩、速度、位置
  • 解决Windows更新后WPF代码报TypeLoadException异常的困难
  • PC与基恩士PLC通信的C#实现
  • Excel 表格技能
  • rk3588的ai功能和deepseek
  • EPSON L1300打印机清零教程
  • tomcat CPU数量和线程数的关系
  • python处理Excel单机小程序:匹数据,增强版VLookup
  • CF623B Array GCD
  • Python爬虫实现双色球历史数据抓取
  • 酵母细胞工厂全球调控策略研究进展:从遗传编辑到智能响应
  • Java实现双色球历史开奖对比器