首页 > 解决方案 > 通过进程队列传递动态创建的 multiprocess.Event()

问题描述

我刚刚开始熟悉 python 中的多处理并陷入了一个我无法以我想要的方式解决的问题,如果我正在尝试的内容甚至可以正确解决,我也找不到任何明确的信息。

我正在尝试做的是类似于以下内容:

import time

from multiprocessing import Process, Event, Queue
from threading import Thread

class Main:
    def __init__(self):
        self.task_queue = Queue()

        self.process = MyProcess(self.task_queue)
        self.process.start()

    def execute_script(self, code):
        ProcessCommunication(code, self.task_queue).start()


class ProcessCommunication(Thread):
    def __init__(self, script, task_queue):
        super().__init__()

        self.script = script
        self.script_queue = task_queue

        self.script_end_event = Event()

    def run(self):
        self.script_queue.put((self.script, self.script_end_event))

        while not self.script_end_event.is_set():
            time.sleep(0.1)


class MyProcess(Process):
    class ExecutionThread(Thread):
        def __init__(self, code, end_event):
            super().__init__()
            self.code = code
            self.event = end_event

        def run(self):
            exec(compile(self.code, '<string>', 'exec'))
            self.event.set()

    def __init__(self, task_queue):

        super().__init__(name="TEST_PROCESS")

        self.task_queue = task_queue

        self.status = None

    def run(self):
        while True:
            if not self.task_queue.empty():
                script, end_event = self.task_queue.get()
                if script is None:
                    break

                self.ExecutionThread(script, end_event).start()

因此,我希望有一个单独的进程,它在我的主进程的整个运行时运行,以在具有受限用户权限、受限命名空间的环境中执行用户编写的脚本。还可以保护主进程免受潜在的无限循环的影响,而无需等待过多的 CPU 内核负载。

使用该结构的示例代码可能如下所示:

if __name__ == '__main__':
     main_class = Main()

     main_class.execute_script("print(1)")

主进程可以同时启动多个脚本,我想将一个事件与执行请求一起传递给该进程,以便在其中一个脚本完成时通知主进程。

但是,Python 进程队列不知何故不喜欢通过队列传递事件并抛出以下错误。

'RuntimeError: Semaphore objects should only be shared between processes through inheritance'

当我为每个执行请求创建另一个事件时,我无法在流程的实例化时传递它们。

我想出了一种解决这个问题的方法,即将一个标识符与代码一起传递,并且基本上设置另一个队列,只要设置了 end_event,就会使用该标识符提供服务。但是,事件的使用对我来说似乎更加优雅,我想知道是否有我还没有想到的解决方案。

标签: pythonpython-3.xmultiprocessing

解决方案


推荐阅读