使用下面的代码我得到了奇怪的输出:
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
输出结果为:
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
我以为我会得到这个:
20120324 20:35:53
3
3
3
1
start worker
worker line
main line
Duration: 1.0
为什么这次运行两次?在WinX64上使用python 2.7:
20120324 20:35:53
3
3
3
1
worker line
答案 0 :(得分:5)
问题基本上是因为multiprocessing
真的被设计为在posix系统上运行,一个系统使用fork(2)
系统调用。在这些操作系统上,进程可以分成两部分,孩子从父进程中神奇地克隆状态,并且两者都恢复在同一个地方运行,子进程现在有一个新的进程ID。在这种情况下,multiprocessing
可以安排一些机制,根据需要将状态从父级传送到子级,确定孩子已经具有大部分所需的python状态。
Windows没有fork()
。
所以multiprocessing
必须收拾残局。这基本上涉及启动运行多处理子脚本的全新python解释器。几乎立即,父母将要求孩子使用父母状态的东西,因此孩子必须从头开始重新创建该状态,将脚本导入孩子。
因此,在脚本中导入时发生的任何事情都会发生两次,一次发生在父级中,一次发生在子级中,因为它重新创建了为父级服务所需的python环境。
答案 1 :(得分:0)
这是我使用Python 2.7.3在Linux上运行代码时得到的结果:
20120324 23:05:49
3
3
3
1
start worker
main line
Duration: 0.0045280456543
worker line
我不知道你为什么会跑两次,但我可以告诉你为什么它没有返回预期的持续时间或以“正确”的顺序打印。
使用multiprocessing
启动进程时,启动是异步的。也就是说,.start()
函数立即在父进程中返回,这样父进程可以继续工作并执行其他操作(如启动更多进程),而子进程在后台执行自己的操作。如果要阻止父进程继续进行直到子进程结束,则应使用.join()
函数。像这样:
def main():
print 'start worker'
p = Process(target=worker, args=())
p.start()
p.join()
print 'main line'