2016-06-28 47 views
2

我正在Raspberry Pi上編寫一個異步視頻播放程序。我需要在子進程中運行omxplayer並在主進程中接收輸入。當收到一些輸入時,主進程會將信號發送到子進程。信號處理程序不能在Python中工作

這裏是我的代碼:

def worker(): 
    p = subprocess.Popen(['omxplayer', '1.mov'], stdin = subprocess.PIPE) 
    def handler(signum, frame): 
     print p.pid 
     p.stdin.write('q') # keystroke of 'q' will quit omxplayer FYI 
    signal.signal(signal.SIGUSR1, handler) # can only be trigger in code 

到目前爲止,似乎罰款。我可以運行worker()並在代碼片段中發送SIGUSR1,並且它工作正常。像這樣:

def test(): 
    worker() 
    time.sleep(5) 
    os.kill(int(os.getpid()), signal.SIGUSR1) 

但是當我嘗試啓動worker作爲多進程時,似乎進程無法接收到信號。

def main_process(): 
    w = multiprocessing.Process(target=worker) 
    w.start() 
    time.sleep(5) 
    os.kill(w.pid, signal.SIGUSR1) 

處理程序不會以這種方式調用。哪部分可能是錯誤的?信號沒有收到,或者綁定不正確?

我覺得os.kill沒有按照我的想法工作。信號根本沒有收到。如何解決這個問題?

回答

2

根據您發佈的代碼,工作人員會撥打Popen設置信號處理程序,然後它將退出。

隨後在您的代碼中調用os.kill會將信號發送到已過期的進程。

通常,最好不要使用信號在進程之間進行通信,而應該使用PipeQueue

以下示例更加健壯和靈活,因爲它允許您向工作人員發送不同的命令。

import subprocess 
import multiprocessing 

def worker(queue): 
    p = subprocess.Popen(['omxplayer', '1.mov'], stdin = subprocess.PIPE) 

    while 1: 
     message = queue.get() # blocks until new message 
     p.stdin.write(message) 

def main(): 
    queue = multiprocessing.Queue() 
    w = multiprocessing.Process(target=worker, args=(queue,)) 
    w.start() 
    queue.put('q') 
+1

Thx很多!這正是我需要的。 – alvinzoo

+0

還有一個問題,當子流程完成後,我應該如何結束工作進程?視頻結束後,我需要打開while循環。 – alvinzoo

+1

而p.returncode爲無:... https://docs.python.org/2/library/subprocess.html#subprocess.Popen.returncode – noxdafox