【问题标题】:What are the recommended ways to deal with multiprocessing and sleep?处理多处理和睡眠的推荐方法是什么?
【发布时间】:2018-06-12 11:40:14
【问题描述】:

所以,这几天我一直在玩 Python 的 multiprocessing 模块,但有些东西我无法理解。也许有人可以给我一点帮助。

我正在尝试从同一类并行运行两个方法,但显然我缺少一些东西:

from multiprocessing import Process
import time


class SomeClass:
    def __init__(self):
        pass

    def meth1(self):
        print(1)
        time.sleep(10)

    def meth2(self):
        print(2)
        time.sleep(5 * 60)


def main():
    while True:
        s = SomeClass()

        p1 = Process(target=s.meth1)  # I want this to run from 10 to 10 seconds
        p1.start()
        p2 = Process(target=s.meth2)  # I want this to run from 5 to 5 minutes
                                      # while the first one still does its own
                                      # job from 10s to 10s
        p2.start()

        p1.join()
        p2.join()


if __name__ == '__main__':
    main()

我期望发生的是:

  • 第一种方法应该打印1;
  • 然后第二个应该打印2(无需等待 10 秒 - 这确实发生并且似乎按预期工作);
  • 那么我应该在接下来的 4 分钟和 50 秒内只看到 1 秒(这不会发生,程序只是等待那个时间过去。

我错过了什么?为什么第二步按预期工作,但第三步没有?我怎样才能让它发挥作用?

【问题讨论】:

  • @wp78de 如果您能想到更好的标题,请随时编辑标题^^
  • meth1 只打印一次1。您为什么希望它继续这样做?
  • @user2357112 因为while True?应该每 10 秒打印一次1 :)
  • 您是否希望 while 循环每 10 秒运行一次 meth1?该循环等待两个进程完成。它必须等待 meth2 完成才能运行另一个 meth1
  • 循环不会等待 p1 完成,直到它已经启动 p2。它会等待两个进程完成,然后再启动新的一批两个进程。

标签: python python-3.x multiprocessing


【解决方案1】:

很难真正知道你想要什么,但下面的代码做了你描述的,但没有方便的退出方式:

from multiprocessing import Process
import time


class SomeClass:
    def __init__(self):
        pass

    def meth1(self):
        while True:
            print(1)
            time.sleep(10)


    def meth2(self):
        while True:
            print(2)
            time.sleep(5 * 60)


def main():
    s = SomeClass()

    p1 = Process(target=s.meth1)  # I want this to run from 10 to 10 seconds
    p1.start()
    p2 = Process(target=s.meth2)  # I want this to run from 5 to 5 minutes while the first one still does its own job from 10s to 10s
    p2.start()

    p1.join()
    p2.join()



if __name__ == '__main__':
    main()

我已将while 移动到SomeClass 的每个方法中

这段代码永远不会退出,挂在p1.join()

【讨论】:

    【解决方案2】:

    将流程视为您的朋友/克隆,您可以通过电话呼叫它们,进来做某事,然后当它们都完成后,它们就回家了,给您留下一个便条。

    线条:

    p1 = Process(target=s.meth1)
    p1.start()
    

    呼叫一个克隆并让他运行s.meth1。他走过来,在你的屏幕上打印 1,等待 10 秒,然后给你留下一张便条:“全部完成,没有异常发生,我已经回家了”。

    同时(当你的第一个克隆即将到来时),这些行:

    p2 = Process(target=s.meth2)
    p2.start()
    

    呼叫另一个克隆并让他运行s.meth2。他过来,在你的屏幕上打印 2,等了大约 5 分钟,然后给你留了一张纸条:“全部完成,没有发生异常,我已经回家了”。

    当克隆 #1 和 #2 正在工作时,行:

    p1.join()
    

    等待克隆 #1 给你留下他的笔记。这发生在 10 秒后。然后你继续:

    p2.join()
    

    它等待克隆 #2 给你留下他的笔记。这会在另外 4 分 50 秒后发生。然后你回到你的while True 重新开始一切。

    如果您希望等待克隆 #2 完成并给您留下他的笔记,请不要致电 p2.join()。不过,最终,您应该致电p2.join(),以确保一切顺利并且他成功回家,并且没有死在你客厅的血泊中,被某些人射杀例外。 :-)

    【讨论】:

    • 不错的 ELI5 答案。虽然...删除 p2.join() 也不会得到想要的结果。删除它仍然会打印1\n2\n1\n2...,这不是我想要的。我希望1\n2\n1\n1\n1\n1\n...2 (after 4 mins and x seconds)... and so on
    • “不要叫它”并不意味着“不要叫它”。此外,如果 p2 仍在运行,您显然也不想再次启动它。您可能会考虑做的是等待任何一个完成。参见,例如,this answer 到相关问题。
    猜你喜欢
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-29
    相关资源
    最近更新 更多