简体   繁体   English

Python多重处理:如何关闭一个长期运行的过程,该过程是一系列操作

[英]Python multiprocessing: How to shutdown a long running process that is a sequence of actions

I want to use multiprocessing to run simultaneously several processes of a series of lengthy actions (eg clicking through programs simultaneously using computer vision). 我想使用多重处理来同时运行一系列冗长动作的多个过程(例如,使用计算机视觉同时单击程序)。 I want to implement a stop button in a GUI that would allow me to stop the processes midway - but I'm not sure how I can do something like that. 我想在GUI中实现一个“停止”按钮,使我可以中途停止进程-但我不确定如何执行类似的操作。

I know I can use a shutdown event to control the processes if there's a loop - however in my case the target function is not a loop. 我知道如果有循环,我可以使用shutdown事件来控制进程-但是在我的情况下,目标函数不是循环。 Here's some code where I basically just did an event check on every line of the target function: 这是一些代码,我基本上只对目标函数的每一行进行了事件检查:

(I deleted a large part of the tkinter code as it's not relevant, the start/stop functions are for their respective buttons in the GUI.) (我删除了tkinter的大部分代码,因为它们无关紧要,启动/停止功能是针对GUI中它们各自的按钮的。)

from multiprocessing import Event, Process
from time import sleep

def start_proc(self):
    self.proc_stop_event.clear()
    for i in range(4):
        p = Process(target=long_sequential_tasks, args=(i,self.proc_stop_event))
        p.start()

def stop_proc(self):
    self.proc_stop_event.set()

#a series of lengthy, different and sequential tasks
def long_sequential_tasks(idx, event):
    if not event.is_set(): <---
        print(str(idx))
        sleep(10) 
    else:
        break
    if not event.is_set(): <---
        print(str(idx * 2))
        sleep(10)
    else:
        break
    if not event.is_set(): <---
        print(str(idx * 3))
        sleep(10)
    else:
        break

Checking the event status every line is obviously not a solution, but I really don't know what else I can do. 检查每一行的事件状态显然不是解决方案,但是我真的不知道还能做什么。 In the future I want to add queues and locks to synchronize the parallel processes, and apparently process.terminate can leave them hanging. 将来,我想添加队列和锁以同步并行进程,显然process.terminate可能会使它们挂起。

So if process.terminate is not an option, how can I interrupt a process that's carrying out a sequence of actions in a clean way? 因此,如果process.terminate不是一个选项,我如何中断以干净方式执行一系列操作的进程? Or I can still terminate the processes but do a clean up on the hanging stuff? 还是我仍然可以终止进程,但是对挂起的东西进行清理?

Q : how can I interrupt a process that's carrying out a sequence of actions in a clean way? 如何中断以干净方式执行一系列操作的流程?

May implement a signaling/messaging metaplane, using nanomsg or ZeroMQ, that will smart-inform the process ( which is checking for presence of such a <NO-GO> -message, as an example in due places in between the phases of the pure-[SERIAL] workflow check-points ) and once a <NO-GO> -message arrives, the process may perform a graceful-cleanup and smart termination of its own run. 可以使用nanomsg或ZeroMQ实现信令/消息元平面,它将智能通知该过程(例如,检查纯净阶段之间适当位置的<NO-GO>消息是否存在) -[SERIAL]工作流检查点),一旦<NO-GO>消息到达,该过程就可以执行正常的清理并自动终止其运行。

The add-on costs are minimal. 附加成本很小。

def long_sequential_tasks( idx ):
    #-----------------------------------------------------------------------
    # local
    # mock-up soft-authentcation proxy
    # for otherwise possible ( whitelisting & key-management & other tools available )
    #
    CONTROL_HASH_ID = "asdfhasrtbnastnve9vaergn9ervgnaeragiagiab - WHATEVER"
    LENofMASK = len( CONTROL_HASH_ID )
    #-----------------------------------------------------------------------
    import zmq
    aCtx = zmq.Context()
    aSUB = aCtx.socket( zmq.SUB )
    aSUB.setsockopt(    zmq.SUBSCRIBE, CONTROL_HASH_ID )
    aSUB.setsockopt(    zmq.LINGER, 0 )
    ...
    aSUB.connect( "<protocol>://<address-details>" ) # { ipc:// | tipc:// | norm:// | tcp:// | vmci:// | ...  }

    if (  0 == aSUB.poll( 0, zmq.POLLIN )
       or      aSUB.recv(    zmq.NOBLOCK )[:LENofMASK] != CONTROL_HASH_ID
           ):                    # <--- NO LEGAL EXPLICIT <NO-GO>-MESSAGE HERE
           # continue planned work-step
           ...

    if (  0 == aSUB.poll( 0, zmq.POLLIN )
       or      aSUB.recv(    zmq.NOBLOCK )[:LENofMASK] != CONTROL_HASH_ID
           ):                    # <--- NO LEGAL EXPLICIT <NO-GO>-MESSAGE HERE
           # continue planned work-step
           ...

The requested effect is achieved in a clean way. 所要求的效果是以干净的方式实现的。

Tkinter MVC-actor-based GUI and any other smart-"sources" of control-messages can live with this concept and initiate smart-signaling/messaging outside the world of the tk.mainloop() -scheduler and easily reach inter-platform integrated computing exo-systems ( using this for more than a decade for a remote GUI for a QuantFX prototyping with AI/ML + trading backend ecosystem ). 基于Tkinter MVC-actor的GUI以及任何其他控制消息的智能“源”都可以使用此概念,并在tk.mainloop()调度程序的外部启动智能信号发送/消息传递,并轻松实现平台间集成计算exo系统(将其用于使用GUI进行AI / ML +交易后端生态系统的QuantFX原型的远程GUI使用了十多年)。


Another way is to implement the exit-plan via a use of a custom-defined signal-handler. 另一种方法是通过使用自定义信号处理程序来实施退出计划。 This releaves the need to structure the sequence of steps after/before which the exit-plan is being checked in a rather rigid way. 这消除了构造步骤顺序的需要,在此之后/之前,以相当严格的方式检查出口计划。 Signal handlers can "interrupt" the flow of computations and may (rather brutally) kill its own process (which needs to add some mitigation measures, if graceful terminations are a must), but represents an option, if loooong running workflow-steps are worth stopping upon some external logic, responsible for the exit-plan flagging a <NO-GO> -state. 信号处理程序可以“中断”计算流程,并且可能(相当残酷地)终止其自己的进程(如果必须优雅地终止,则需要添加一些缓解措施),但如果可以长期运行工作流步骤,则可以选择停止一些外部逻辑,负责退出计划标记<NO-GO>状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM