【问题标题】:Code wont excuted by order in __name__ == '__main__'代码不会按 __name__ == \'__main__\' 中的顺序执行
【发布时间】:2023-02-06 03:14:13
【问题描述】:

我正在尝试一些多处理作为下面的示例代码,它应该打印来自01,02,03,hello world,04,05的消息,但它却去了01,02,01,05,03,hello world,04,05,为什么02回到01然后跳转到05,回到03,为什么我在这里错过了吗,如何让它按顺序运行,谢谢!

from multiprocessing import *

# large data/complex use multiprocessing , else use odinary function
q = Queue() # comm between parent n child proces
    

def f1(x,q):
    print('03')
    x = x + " world"
    q.put(x)


def main_f():
    print('01')
    mp = Process(target=f1,args=("hello",q,))

    if __name__ == '__main__': # only happen once, else ex 4 process to 16 to 64 endless
        print('02')

        mp.start()
        print(q.get())
        mp.join()

        print('04')

main_f()
print('05')

我期待来自 01,02,03,hello world,04,05 的消息打印

【问题讨论】:

  • 向我们展示您是如何运行这段代码的。
  • 在像多处理这样的并发执行中不能保证输出的顺序。它可以随着每次运行而改变。如果希望输出按特定顺序,可以使用队列在进程之间传递消息,并确保进程按特定顺序执行。
  • @AhmedAEK 不完全是

标签: python multiprocessing queue program-entry-point


【解决方案1】:

当您在使用产卵方法来创建新进程,那么全局范围内不在 if __name__ == '__main__': 块内的任何代码将首先由子进程执行,以便在调用工作函数 f1 之前初始化其存储。

在您发布的代码中,当创建子进程时,它将因此按顺序执行以下语句:

  1. from multiprocessing import *
  2. q = Queue() # 创建全局队列
  3. def f1(x, q): # 创建函数定义
  4. def main_f(): # 创建函数定义
  5. main_f() # 调用 main_f
  6. print('05')

    实际上,在调用 worker 方法 f1 之前,子进程唯一需要执行的语句是上面的语句 #3,它为子进程定义了 worker 函数。

    语句 1 导入您的子进程未使用的包。这样做不会阻止程序正确运行,但 Python 会花时间执行未使用的导入。

    语句 #2 在子进程中不必要地创建了一个新的队列实例,该队列实例与在主进程中创建的队列实例不同。如果您的子进程使用它,那将是灾难性的,因为它将把元素放在与主进程从中获取的队列不同的队列中。幸运的是,函数f1 没有引用和使用作为参数传递的队列。

    语句#4 定义了一个未被子进程使用的函数。它不会阻止程序运行但很浪费。

    语句 #5 调用 main_f这就是你的麻烦开始的地方。main_f 中不在 if __name__ == '__main__': 块中的所有代码将在调用辅助函数之前立即执行。这就是导致打印额外“01”的原因。

    语句 #6 同样是导致打印额外“05”的原因。

    因此,至少要让您的程序正常工作,您的代码应该是:

    from multiprocessing import *
    
    def f1(x,q):
        print('03')
        x = x + " world"
        q.put(x)
    
    
    def main_f():
        # large data/complex use multiprocessing, else use ordinary function
        q = Queue() # comm between parent n child process
    
        print('01')
        mp = Process(target=f1,args=("hello",q,))
    
        print('02')
    
        mp.start()
        print(q.get())
        mp.join()
    
        print('04')
    
    if __name__ == '__main__':
        main_f()
    

    如果我们想消除所有可能的低效率,即防止在子进程初始化时执行不必要的语句,那么:

    def f1(x,q):
        print('03')
        x = x + " world"
        q.put(x)
    
    if __name__ == '__main__':
        from multiprocessing import *
    
        def main_f():
            # large data/complex use multiprocessing, else use ordinary function
            q = Queue() # comm between parent n child process
    
            print('01')
            mp = Process(target=f1,args=("hello",q,))
    
            print('02')
    
            mp.start()
            print(q.get())
            mp.join()
    
            print('04')
    
        main_f()
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-17
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 2017-07-30
    • 2021-03-16
    • 1970-01-01
    • 2018-10-02
    相关资源
    最近更新 更多