中断python多进程.在Windows中使用信号进行处理



我有一个python脚本,它使用multiprocessing生成一个新的Process。流程类。这个进程应该永远运行以监视东西。在Unix上,我现在可以使用os.kill()向该特定进程发送信号,并在该进程中使用signal.signal(…)来实现我的特定中断处理程序。

我读了如何使用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

我找到了一个解决方案,使用multiprocessing.Event类实现信令。

线索是然后找到interrupt_main()方法(它在thread (Python2)或_thread (Python3)中),它在主线程中引发KeybordInterrupt,这是我想要中断的进程。

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

相关内容

  • 没有找到相关文章

最新更新