【问题标题】:Python Multiprocessing outside of main producing unexpected result主要产生意外结果之外的Python多处理
【发布时间】:2020-10-29 02:51:27
【问题描述】:

我有一个程序每分钟调用一次 API 并执行一些操作,当满足某些条件时,我想创建一个新进程,它将每秒调用另一个 API 并执行一些操作。父进程并不关心这个子进程产生的结果,子进程将自行运行,直到一切都完成。这样父进程就可以每分钟不断地调用api,不间断地进行操作。

我研究了多处理。但是我不能让它在 ma​​in 之外工作。我尝试传递一个回调函数,但这产生了意想不到的结果(父进程在某个时候再次开始并行运行)。

我能想到的另一个解决方案是创建另一个项目,然后提出请求。但是这样我就会有很多重复的代码。

解决我的问题的最佳方法是什么?

示例代码:

class Main:
    [...]
    foo = Foo()
    child = Child()

    foo.Run(child.Process)
    


class Foo:
    [...]
    def Run(callbackfunction):
        while(True):
            x = self.dataServices.GetDataApi()
            if(x == 1020):
                callbackfunction()
                #start next loop after a minute
    

class Child:
    [...]
    def Compute(self):
        while(True):
            self.dataServics.GetDataApiTwo()
            #do stuff
            #start next loop after a second

    def Process(self):
        self.Compute() # i want this function to run from a new process, so it wont interfer

Edit2:在多进程尝试中添加

class Main:

    def CreateNewProcess(self, callBack):
        if __name__ == '__main__':
            p = Process(target=callBack)
            p.start()
            p.join()
        
    foo = Foo()
    child = Child(CreateNewProcess)

    foo.Run(child.Process)
    


class Foo:
    def Run(callbackfunction):
        while(True):
            x = dataServices.GetDataApi()
            if(x == 1020):
                callbackfunction()
            #start next loop after a minute
    

class Child:
    _CreateNewProcess = None

    def __init__(self, CreateNewProcess):
        self._CreateNewProcess = CreateNewProcess

    def Compute(self, CreateNewProcess):
        while(True):
            dataServics.GetDataApiTwo()
            #do stuff
            #start next loop after a second

    def Process(self):
        self.CreateNewProcess(self.Compute) # i want this function to run from a new process, so it wont interfer

【问题讨论】:

  • 多处理是一个好方法。有关您的问题的详细信息,您应该在问题中显示格式正确的相关代码。
  • 为每个进程运行主检查之外的代码:stackoverflow.com/questions/31858352/…
  • @MichaelButscher 嘿,我刚刚添加了一个示例代码。你能给我一些建议吗?我应该添加使用多进程的尝试吗?它不起作用,所以我不想混淆
  • 在您的“主”类中,您创建实例并在其中调用一个方法。这应该在 Python 文档中关于多处理的描述的 if __name__ == "__main__": 保护之外非常小心地完成。我认为不应该在这里进行。您应该展示如何尝试使用多处理。这是正确的方法,应该可以解决您的问题。
  • @MichaelButscher 感谢您的回复。我刚刚在示例代码上添加了我对多处理的尝试。我创建了一个回调用于在 main 中创建一个新进程,然后将其传递给子类以便它可以使用它。但我认为由于 Mike67 提到的原因,这行不通。我尝试打开守护程序但仍然无法正常工作,我迷路了,请指教

标签: python multiprocessing


【解决方案1】:

我不得不重新组织一些事情。其中:

  • 守卫if __name__ == '__main__': 应该包括创建 对象,尤其是对函数和方法的调用。通常是 放在代码末尾的全局级别。

  • 不应在主进程中创建子对象。理论上你可以 这样做是为了将它们用作孩子必要数据的容器 处理,然后将它们作为参数发送,但我认为是单独的 如有必要,应为此使用类。在这里我使用了一个 简单的data 参数,可以是任何可腌制的东西。

  • 将全局级别的功能作为进程更简洁 目标(在我看来)

最后看起来像:

from multiprocessing import Process

class Main:
    @staticmethod
    def CreateNewProcess(data):
        p = Process(target=run_child, args=(data,))
        p.start()
        p.join()


class Foo:
    def Run(self, callbackfunction):
        while(True):
            x = dataServices.GetDataApi()
            if(x == 1020):
                callbackfunction(data)
            #start next loop after a minute


class Child:
    def __init__(self, data):
        self._data = data

    def Compute(self):
        while(True):
            dataServics.GetDataApiTwo()
            #do stuff
            #start next loop after a second



# Target for new process. It is cleaner to have a function outside of a
# class for this

def run_child(data):   # "data" represents one or more parameters from
                       # parent to child necessary to run specific child.
                       # "data" must be pickleable.
                       # Can be omitted if unnecessary
    global child
    child = Child(data)
    child.Compute()


if __name__ == '__main__':
    foo = Foo()

    foo.Run(Main.CreateNewProcess)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多