首先,你的输出完全是巧合,你可以多执行几次,或者把map的第二个参数,即那个列表变长一些,输出完成是乱的,因为多进程本来就是同时进行,你又没有进行同步操作,所以是并行输出的。
其次,global 定义的lst,foo在主线程和poo启动的多个进程间是不共享的,但是因为pool的内部机制,进程间会共享lst变量,所以状态会被多个进程同时更改。而在if __name__ == '__main__':函数里面的lst变量和进程运行时的main函数里面的lst内存地址不同,不共享。至于为什么有时会有‘lst in main: [0, 1, 2]’这样的输出,完全是因为正好0,1,2作为参数的进程恰好顺序执行完。
测试代码如下,输出了变量的id
# coding: utf-8
from multiprocessing import Pool
foo = 0
lst = []
print "sss", id(lst)
def main(offset):
global lst
global foo
lst.append(offset)
foo += 1
print("lst in main:", lst, id(lst))
print('foo in main:', foo, id(foo))
return lst, foo
if __name__ == '__main__':
pool = Pool(processes=3)
results = pool.map(main, range(3))
lst.append(10)
pool.close()
pool.join()
print("lst:", lst, id(lst))
print('foo:', foo, id(foo))
pass
输出可能是:
sss 35828640 # 最初创建的lst
sss 4404288 # 执行Pool()时创建了新的lst
('lst in main:', [0], 4404288) # 进程共享lst
('foo in main:', 1, 4936864)
('lst in main:', [0, 1], 4404288) # 进程共享lst
('foo in main:', 2, 4936852)
('lst in main:', [0, 1, 2], 4404288) # 进程共享lst
('foo in main:', 3, 4936840)
sss 3421248 # 执行Pool()时创建了新的lst,不知为何没用到
sss 29766720 # 执行Pool()时创建了新的lst,不知为何没用到
('lst:', [10], 35828640) # 和最初创建的lst一致
('foo:', 0, 34362540)
另外,if __name__=='__main__':里面的变量本身就是全局的,不用再global 声明
进程间共享数据可以通过multiprocessing的Manager,按作者需求改了之后的代如下:
# coding: utf-8
from multiprocessing import Pool, Manager
def main(params):
lst = params[0]
offset = params[1]
print lst, offset
lst.append(offset)
if __name__ == '__main__':
pool = Pool()
manager = Manager()
lst = manager.list()
pool_outputs = pool.map(main, [param for param in
[(lst, l) for l in range(10)]])
print lst
输出为:
[] 0
[0] 1
[0, 1] 2
[0, 1, 2] 3
[0, 1, 2, 3] 4
[0, 1, 2, 3, 4] 5
[0, 1, 2, 3, 4, 5] 6
[0, 1, 2, 3, 4, 5, 6] 7
[0, 1, 2, 3, 4, 5, 6, 7] 8
[0, 1, 2, 3, 4, 5, 6, 7, 8] 9
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]