繁体   English   中英

使用gevent和stdin管理子流程

[英]Managing a subprocess with gevent and stdin

我编写了一个小程序来启动和停止从stdin读取命令的子进程,使用gevent希望有效地等待命令输入和进程完成。

它有一个命令R -run,它将stdin读为一行。

R只是从脚本sleep 2; echo "Hello, world!"开始sh sleep 2; echo "Hello, world!" sleep 2; echo "Hello, world!" 如果尚未运行

有两个Greenlet,一个为读取命令输入,另一个为等待新进程或等待当前进程完成。 我使用gevent Event在两者之间切换。

我的问题:该流程的准入门槛永远都无法完成。 命令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读取完成,我希望它具有某些select例如行为,当两个greenlet等待某事时,它将在首先完成的greenlet中恢复执行。

对于我自己的问题,我有两种解决方案。 这些都可以使我的示例程序按预期运行。

标准管

使用Popen(..., stdin=PIPE)打开子Popen(..., stdin=PIPE) 有意义的是,如果没有它,gevent就无法工作,因为它必须等待某些事情

使用FileObjectThread

不管子流程是如何创建的,这似乎都可行,不确定为什么

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM