2016-10-26 9 views
1

私は、multiprocessing.Processクラスを使用して新しいプロセスを生成するpythonスクリプトを持っています。このプロセスは、物事を監視するために永遠に実行されるはずです。 Unixでは、os.kill()を使用して特定のプロセスに信号を送信し、そのプロセス内のsignal.signal(...)を使用して、特定の割り込みハンドラを実装することができます。 Windowsでは動作しません。は、Pythonマルチプロセッシングを中断します。Windowsのシグナルを使用しているプロセス

popenを使用してそれを行う方法を読んでいます。 ProcessクラスのCREATE_NEW_PROCESS_GROUPフラグも指定できますか?そしてどうやって?ここ

は私のサンプルコードです:

import multiprocessing as mp 
import time 
import signal 
import os 
import platform 

def my_h(signal, frame): 
    print("recieved signal", signal) 
    raise InterruptedError 

def a_task(): 
    signal.signal(signal.SIGINT, my_h) 
    print("this is 'a_task'", os.getpid()) 
    try: 
     while True: 
      print(time.time()) 
      time.sleep(1) 
    except Exception as e: 
     print(type(e), e) 
    print("'a_task' is at end") 


if __name__ == '__main__': 
    p = mp.Process(target=a_task) 
    p.start() 
    time.sleep(1) 

    if platform.system() == 'Windows': 
     print("send CTRL_C_EVENT") 
     os.kill(p.pid, signal.CTRL_C_EVENT) 
    elif platform.system() == 'Linux': 
     print("send SIGINT") 
     os.kill(p.pid, signal.SIGINT) 

    time.sleep(3) 
    try: 
     os.kill(p.pid, signal.SIGTERM) 
    except: 
     pass 
+0

多分この:http://tweaks.com/windows/39559/kill-processes-from-command-prompt/ –

+0

私はこの他の解決策は、あなたの問題を解決すると思います。 http://stackoverflow.com/questions/1230669/subprocess-deleting-child-processes-in-windows#4229404 – mydaemon

+0

これは単にプロセスを終了させることではなく、停止の前に 'except'節が実行されることを保証することです。 – cima

答えて

1

私はみかんmultiprocessing.Eventクラスを使用してシグナリングを実装する、回避策を見つけました。

手がかりは、私が中断するプロセスであるメインスレッドでKeybordInterruptを上げる(thread(Python2)または_thread(のpython3)のいずれかである)interrupt_main()方法を見つけることが、その後でした。

import multiprocessing as mp 
import time 
import signal 
import os 
import threading 
import _thread 

def interrupt_handler(interrupt_event): 
    print("before wait") 
    interrupt_event.wait() 
    print("after wait") 
    _thread.interrupt_main() 

def a_task(interrupt_event, *args): 
    task = threading.Thread(target=interrupt_handler, args=(interrupt_event,)) 
    task.start() 

    print("this is 'a_task'", os.getpid()) 
    try: 
     while True: 
      print(time.time()) 
      time.sleep(1) 
    except KeyboardInterrupt: 
     print("got KeyboardInterrupt") 
    print("'a_task' is at end") 


if __name__ == '__main__': 
    interrupt_event = mp.Event() 
    p = mp.Process(target=a_task, args = (interrupt_event, tuple())) 
    p.start() 
    time.sleep(2) 
    print("set interrupt_event") 
    interrupt_event.set() 

    time.sleep(3) 
    try: 
     os.kill(p.pid, signal.SIGTERM) 
    except: 
     pass 
+0

これは動作しますが、通常、各プロセスのメインスレッドは、イベントを待機または定期的にポーリングし、ワーカースレッドが正常に終了するようにシグナルを設定します。 – eryksun

+0

まあ、それも私の最初のアイデアでした。しかし、かなりの時間の間、本当に大事な数字であるタスクを考えてみてください。そのプロセスを中断したいのであれば、それはワーカー(非メイン)スレッドを中断させることを意味します。私は従業員が反応しないときの方法を見つけませんでした。 Unixでは、SIGINTを送信し、try以外でtryをキャッチします。上記の解決策は、Unixワークフローと多少似ています。しかし、とにかくコメントのためにthx。 – cima

+0

私は重大な数値の処理がC拡張にオフロードされることを期待しています。その点に関しては、ほとんどの組み込み関数が中断されていることをサポートしていません。彼らはGILをリリースし、自分のことをするために出かける。それがメインスレッドであれば、Pythonがシグナルを処理するのでホースします。したがって、インタプリタがメインスレッドで実行されるときにインタープリタのフラグを設定する 'interrupt_main'関数です。 – eryksun

関連する問題