0
我已經編寫了一個小程序來啓動和停止從stdin讀取命令的子進程,使用gevent來希望高效地等待命令輸入和進程完成。用gevent和stdin管理一個子進程
它有一個命令R
- 運行,它將stdin讀作一行。
R
簡單的腳本sleep 2; echo "Hello, world!"
開始SH如果尚未運行
有兩個greenlets,一個讀命令輸入和一個等待新的流程或等待當前進程完成。我使用gevent Event
在兩者之間切換。
我的問題:該過程的greenlet永遠不會完成。命令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
一起使用,所以我認爲這是好的。 - 如果我打破調試器堆棧跟蹤顯示正在等待從標準輸入讀取完成,我預計它會有一些
select
類似的行爲,並且當兩個greenlet正在等待的東西它會執行將繼續在greenlet首先完成。