试图在python中使用main来理解多处理

Mer*_*lin 3 python program-entry-point multiprocessing

使用下面的代码我得到奇怪的输出:

import  sys 
from  multiprocessing import Process
import time
from time import strftime

now =time.time()    
print time.strftime("%Y%m%d %H:%M:%S", time.localtime(now)) 

fr= [1,2,3]
for row in fr:
    print 3

print 1

def worker():
    print 'worker line'
    time.sleep(1)
    sys.exit(1)

def main():
    print 'start worker'
    Process(target=worker, args=()).start()
    print 'main line'

if __name__ == "__main__":
    start_time = time.time()
    main()
    end_time = time.time()
    duration = end_time - start_time
    print "Duration: %s" % duration
Run Code Online (Sandbox Code Playgroud)

输出是:

20120324 20:35:53
3
3
3
1
start worker
main line
Duration: 0.0
20120324 20:35:53
3
3
3
1
worker line 
Run Code Online (Sandbox Code Playgroud)

我以为我会得到这个:

20120324 20:35:53
3
3
3
1
start worker
worker line
main line
Duration: 1.0
Run Code Online (Sandbox Code Playgroud)

为什么这次运行两次?在WinX64上使用python 2.7:

20120324 20:35:53
3
3
3
1
worker line 
Run Code Online (Sandbox Code Playgroud)

Sin*_*ion 5

问题基本上是因为multiprocessing它真的被设计为在posix系统上运行,一个用fork(2)syscall运行.在这些操作系统上,进程可以分成两部分,孩子从父进程中神奇地克隆状态,并且两者都恢复在同一个地方运行,子进程现在有一个新的进程ID.在那种情况下,multiprocessing可以根据需要安排一些机制将状态从父级传送到子级,确定孩子已经具有大部分所需的python状态.

Windows没有fork().

所以multiprocessing必须收拾残局.这基本上涉及启动运行多处理子脚本的全新python解释器.几乎立即,父母将要求孩子使用父母状态的东西,因此孩子必须通过将脚本导入孩子来从头开始重新创建该状态.

因此,在脚本中导入时发生的任何事情都会发生两次,一次发生在父级中,一次发生在子级中,因为它重新创建了为父级提供服务所需的python环境.