今天遇到了一个很让人费解的问题。问题的起因是没有把多进程程序写在 __main__下面( windows 系统下) 然后就尴尬了。
以前学习多进程是在 Linux 下,用的较多的是 fork ,今天遇到的问题,很有意思,所以就写下来。
# -*- coding: utf-8 -*-
__author__ = 'bigboydream'
import random
from multiprocessing import Process
import os
print('I am ', os.getpid())
rand_num = random.randint(0, 20)
def foo():
print('I am {}, rand_num is {}'.format(os.getpid(), rand_num)) # 子进程的 rand_num
if __name__ == "__main__":
print('I am {}, rand_num is {}'.format(os.getpid(), rand_num)) # 父进程的 rand_num
p = Process(target=foo)
p.start()
p.join()
'''
I am 16880
I am 16880, rand_num is 10
I am 7592 # 执行了两次 print('I am ', os.getpid())...
I am 7592, rand_num is 2 # 父进程和子进程的 rand_num 居然不一样...
'''
用 fork 的思维想了一下 第一: print('I am ', os.getpid()),应该只能执行一次啊 第二: rand_num 应该一样啊
但是出现了不一样的结果,难道 p.start()的时候,
import random
from multiprocessing import Process
import os
print('I am ', os.getpid())
rand_num = random.randint(0, 20)
'''
又执行了一遍!!!
'''
所以得到了以上的结果。
难怪多进程程序不写在__main__下面会出现错误,不然就一直在递归地创建子进程了。
一样的代码在 Linux 下运行
# -*- coding: utf-8 -*-
__author__ = 'bigboydream'
import random
from multiprocessing import Process
import os
print('I am ', os.getpid())
rand_num = random.randint(0, 20)
def foo():
print('I am {}, rand_num is {}'.format(os.getpid(), rand_num)) # 子进程的 rand_num
print('I am {}, rand_num is {}'.format(os.getpid(), rand_num)) # 父进程的 rand_num
p = Process(target=foo)
p.start()
p.join()
'''
I am 3811
I am 3811, rand_num is 17
I am 3841, rand_num is 17
'''
'''
感觉好像靠谱了
'''
用 fork 呢?
# coding : utf-8
import os
import random
print('I am ', os.getpid())
rand_num = random.randint(0, 20)
ret = os.fork()
if ret==0:
print('child pid is {}, rand_num is {}'.format(os.getpid(), rand_num))
else:
print('parent pid is {}, rand_num is {}'.format(os.getpid(), rand_num))
'''
I am 4054
parent pid is 4054, rand_num is 12
child pid is 4084, rand_num is 12
'''
'''
真好
'''
但是有一个问题就是 multiprocessing 在 Linux 系统上和 windows 系统下表现不一致, Linux 系统下 Python 用 fork 实现了多进程?
请问学习多进程有什么好的资料吗?想多学一点这方面的知识,今天搞的有点懵圈
1
polythene 2017-01-05 22:19:20 +08:00 1
这次修坑的过程就是最好的学习资料~
https://docs.python.org/2/library/multiprocessing.html#windows 官方文档也写了 multiprocessing 在 Windows 平台的不一致性。 |
2
neoblackcap 2017-01-05 23:11:39 +08:00 1
Windows 下没有 fork ,表现不一样不是很正常的吗?而且 Windows 的进程模型跟 linux 也不一样
|
3
Allianzcortex 2017-01-05 23:33:33 +08:00 1
posix 线程和 Windows 线程是不一样的底层实现机制嘛
|
4
wwqgtxx 2017-01-06 07:52:52 +08:00 via iPhone 1
python2 和 3 的官方文档都写了, multiprocessing 在 wun 上的实现是开启一个新进程,而在 posix 环境下默认使用 fork 方式。当然这个启动方式是可以更改的,可以在初始化 Process 的时候指定启动方式( win 下 fork 不可用而已)
|
5
wisefree OP @polythene 恩,当初没仔细看文档,现在来好好看看。以前都是以为底层实现机制都被封装,一样的代码能够得到一样的结果,这才是跨平台嘛。。看来还是书读少了
|
6
wisefree OP @neoblackcap 。没有太了解进程模型,一直以为一样的 python 代码会在不同的平台得到一样的结果,所以这次增加了一点经验。
|
7
wisefree OP @Allianzcortex 厉害呀,我并不了解底层实现机制
|