Python 使用gevent和stdin管理子流程
我已经编写了一个小程序,通过从stdin读取命令来启动和停止子进程,希望使用gevent有效地等待命令输入和进程完成 它有一个命令Python 使用gevent和stdin管理子流程,python,gevent,Python,Gevent,我已经编写了一个小程序,通过从stdin读取命令来启动和停止子进程,希望使用gevent有效地等待命令输入和进程完成 它有一个命令R-run,它将stdin作为一行读取 R只是用脚本sleep 2启动sh;如果尚未运行,则回显“Hello,world!” 有两个greenlet,一个读取命令输入,另一个等待新进程或当前进程完成。我使用gevent事件在两者之间切换 我的问题是:这个过程的底线是永远不允许完成。greenlet命令似乎始终在运行,并且从不放弃控制。为什么greenlet的过程永远不
R
-run,它将stdin作为一行读取
R
只是用脚本sleep 2启动sh;如果尚未运行,则回显“Hello,world!”
有两个greenlet,一个读取命令输入,另一个等待新进程或当前进程完成。我使用gevent事件
在两者之间切换
我的问题是:这个过程的底线是永远不允许完成。greenlet命令似乎始终在运行,并且从不放弃控制。为什么greenlet的过程永远不会从等待中醒来,即使过程显然已经结束了
资料来源如下:
import sys
from gevent import spawn, joinall, sleep
from gevent.subprocess import Popen
from gevent.fileobject import FileObjectPosix
from gevent.event import Event
process = None
trigger = Event()
def start_process():
global process
process = Popen(['/bin/sh', '-c', 'sleep 2; echo Hello, World!'])
def wait_process():
global process
while True:
trigger.wait()
print('INFO - Awaiting new process')
trigger.clear()
process.wait()
process = None
print('INFO - Process done')
def get_input():
global process
stdin_wrapped = FileObjectPosix(sys.stdin)
while True:
line = stdin_wrapped.readline().decode().strip()
if line == 'R':
if not process:
start_process()
trigger.set()
print('OK - Running process')
else:
print('FAIL - Process already running')
sleep(0)
def main():
joinall([
spawn(get_input),
spawn(wait_process)
])
if __name__ == '__main__':
main()
会话如下所示,R
s之间的间隔大于2s:
R
OK - Running process
INFO - Awaiting new process
Hello, World!
R
FAIL - Process already running
我希望看到:
R
OK - Running process
INFO - Awaiting new process
Hello, World!
INFO - Process done
R
OK - Running process
我最初的想法是,有两件事出了问题:
- 这不是使用gevent读取文件的正确方法
- 子流程等待事件未被正确使用,并且它从未唤醒。我没有见过这样使用它的例子,但是Popen对象可以与
一起使用,所以我认为这是可以的gevent.wait
- 如果我中断调试器,堆栈跟踪显示正在等待从stdin读取完成,我希望它会有一些类似
的行为,当两个greenlet正在等待某个内容时,它将在首先完成的greenlet中恢复执行select
- 对于我自己的问题,我有两种解决方案。这两个选项中的任何一个都将使我的示例程序按预期运行
标准管道
使用
Popen(…,stdin=PIPE)
打开子流程。如果没有它,gevent将无法工作,这是有道理的,因为它必须等待一些东西
使用FileObjectThread
无论子流程是如何创建的,这似乎都是有效的,不知道为什么