[英]Managing a subprocess with gevent and stdin
I have written a small program to start and stop a subprocess on command from read from stdin, using gevent to, hopefully, efficiently wait for both the command input, and for the process to finish. 我编写了一个小程序来启动和停止从stdin读取命令的子进程,使用gevent希望有效地等待命令输入和进程完成。
It has one command R
- run, which it read of stdin as a line. 它有一个命令
R
-run,它将stdin读为一行。
R
simply starts sh with the script sleep 2; echo "Hello, world!"
R
只是从脚本sleep 2; echo "Hello, world!"
开始sh sleep 2; echo "Hello, world!"
sleep 2; echo "Hello, world!"
if it is not already running 如果尚未运行
There are two greenlets, one reading command input and one waiting for a new process or waiting for the current process to finish. 有两个Greenlet,一个为读取命令输入,另一个为等待新进程或等待当前进程完成。 I use an gevent
Event
to toggle between the two. 我使用gevent
Event
在两者之间切换。
My problem: The greenlet for the process is never allow to finish. 我的问题:该流程的准入门槛永远都无法完成。 The command greenlet appears to always be running and never relinquishes control.
命令greenlet似乎始终在运行,并且永不放弃控制权。 Why does the process greenlet never wake from its wait, even when the process is clearly finished?
为什么即使进程显然已经完成,进程greenlet也从不从等待中唤醒?
The source is as follows: 来源如下:
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()
A session looks like this, with a >2s gap between the R
s: 会话看起来像这样,
R
s之间的间隔大于2s:
R
OK - Running process
INFO - Awaiting new process
Hello, World!
R
FAIL - Process already running
I expect to see: 我希望看到:
R
OK - Running process
INFO - Awaiting new process
Hello, World!
INFO - Process done
R
OK - Running process
My initial ideas are one of two things are going wrong: 我最初的想法是出了两件事之一:
gevent.wait
so I assumed this was ok. gevent.wait
一起使用,所以我认为这没问题。 select
like behaviour, and when two greenlets were waiting on something it would execution would resume in the greenlet that finished first. select
例如行为,当两个greenlet等待某事时,它将在首先完成的greenlet中恢复执行。 I have two solutions to my own problem. 对于我自己的问题,我有两种解决方案。 Either of these will make my example program function as expected.
这些都可以使我的示例程序按预期运行。
Open the subprocess with Popen(..., stdin=PIPE)
. 使用
Popen(..., stdin=PIPE)
打开子Popen(..., stdin=PIPE)
。 It makes sense that gevent won't work without that since it must wait on something . 有意义的是,如果没有它,gevent就无法工作,因为它必须等待某些事情 。
FileObjectThread
FileObjectThread
This seems to work regardless of how the subprocess is created, not sure why 😐 不管子流程是如何创建的,这似乎都可行,不确定为什么
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.