python定义变量差异before/after主块

python define variable difference before/after main block

python 在主块之前或之后定义变量有什么区别?请参阅以下代码示例中的变量 "lock"。

以下代码有效:

import multiprocessing
from multiprocessing import Lock

lock=Lock()

def single_process(num):
    lock.acquire()
    print(num)    
    lock.release()

if __name__ == "__main__":
    p1 = multiprocessing.Process(target=single_process, args=(123,)) 
    p2 = multiprocessing.Process(target=single_process, args=(456,)) 

    p1.start() 
    p2.start()

    p1.join()    
    p2.join()

但是下面的代码不起作用,说锁没有定义:

import multiprocessing
from multiprocessing import Lock

def single_process(num):
    lock.acquire()
    print(num)    
    lock.release()

if __name__ == "__main__":

    lock=Lock()

    p1 = multiprocessing.Process(target=single_process, args=(123,)) 
    p2 = multiprocessing.Process(target=single_process, args=(456,)) 

    p1.start() 
    p2.start()

    p1.join()    
    p2.join()

您应该通过 args 将锁传递给子进程。


解释:

我认为你是 运行 这个 Windows。无论哪种方式,您都不应该期望您在父进程中声明的所有变量或您设置的值都自动在子进程中可用。有关向子进程共享数据的不同方式,请参阅 this for synchronisation (locks) and and this

就是说,您发布的两个代码片段在我的系统上对我来说都是 运行 (Linux)。 Linux 的区别在于,fork() 系统调用用于启动新进程。 Fork 复制调用进程。所以它继承了主进程的状态。

在您的代码中的 Windows, there is no fork() system call. So when a child is created, the module is reloaded in the child processes without the __name__ set to __main__ (otherwise it would lead to a fork bomb 上)。因此,在您的第一个代码段中,lock 变量也将在子进程中设置,因为它不在 if __name__ == "__main__" 中。但是在您的第二个代码段中,不会设置锁定变量,因为它位于 if __name__ == "__main__" 块内。