我的测试脚本test.py
如下:
import time
from multiprocessing import Pool
n = []
print('global', id(n))
def slowf():
global n
time.sleep(5)
n.append(1)
print('slowf---', n, id(n))
def checkn():
global n
while 1:
if n:
print('checkn', n, id(n), "T")
break
else:
print('checkn', n, id(n), "F")
time.sleep(1)
def main():
global n
p = Pool()
p.apply_async(slowf, args=())
p.apply_async(checkn, args=())
p.close()
p.join()
if __name__ == '__main__':
main()
在python3.6
中运行的脚本输出是:
global 4534751304
checkn [] 4534751304 F
checkn [] 4534751304 F
checkn [] 4534751304 F
checkn [] 4534751304 F
checkn [] 4534751304 F
slowf--- [1] 4534751304
checkn [] 4534751304 F
checkn [] 4534751304 F
checkn [] 4534751304 F
checkn [] 4534751304 F
checkn [] 4534751304 F
......
那么,为什么slowf()
函数在5秒后更改了全局变量n
,但它仍然在[]
函数中读取checkn()
。他们只是使用相同的n
进入全局var id
。我只是困惑!
如果有人能向我解释,我感激不尽! 谢谢你!
答案 0 :(得分:1)
单独的进程不共享内存。您在一个孩子中所做的更改在另一个孩子中无法看到。
The docs解释了这一点,以及为什么你经常不想要共享状态(你需要添加同步,这是很难做到的),以及你也是可以改为。
You can use explicit shared memory, but only with basic "C types" like 32-bit integers or arrays of floats。然后,您必须在正确的位置使用Lock
之类的显式同步,以使您的代码安全。
如果可能,理想的解决方案是将代码重新设计为pass data over queues instead of sharing it。
如果这不适合您的问题,您可以使用Manager
,这基本上会在队列顶部伪造共享的高级Python对象。对于某些用途来说,这可能会非常缓慢,但是当它不是时,它可能是最简单的答案。