Python 多进程和全局变量

3
import os
from multiprocessing import Process

b = {
        'x':{
            'd':[]
            },
        'y':{
            'd':[]
            },
}

def fmt():
    global b
    for k in b:
        if not b[k]['d']:
            b[k]['d'].append("fb1")
        print b
        t = Process(target=fb2, args=(k,))
        t.daemon = False
        t.start()

def fb2(k="x"):
    print os.getpid(), k, b[k]

if __name__ == '__main__':
    fmt()

Windows输出:

C:\Python27\python.exe C:/Users/qchen/PycharmProjects/syntax_test/syntax_test.py
{'y': {'d': ['fb1']}, 'x': {'d': []}}
{'y': {'d': ['fb1']}, 'x': {'d': ['fb1']}}
4412 y {'d': []}
5972 x {'d': []}

Linux 输出:

qchen@ubuntu:~/PycharmProjects/for_test$ python syntax_test.py 
{'y': {'d': ['fb1']}, 'x': {'d': []}}
{'y': {'d': ['fb1']}, 'x': {'d': ['fb1']}}    
23547 y {'d': ['fb1']}
23548 x {'d': ['fb1']}

我不知道为什么Windows操作系统和Linux操作系统之间会有差异;这种差异是由于两个操作系统中进程分叉和管理的不同所导致的。


1
你为什么要一开始就使用全局变量呢?不要成为那种人。 - ThiefMaster
看起来在Linux上你打印了b[k](尽管你的代码),而在Windows上你确实打印了b(如代码所述)。由于使用的代码存在差异(至少这是最简单的解释),你可能搞砸了其他东西。我建议比较你在两个系统上运行的两个版本,消除所有差异,然后重试该实验。那么可能就没有这些奇怪的问题了。 - Alfe
第一次打印是我的错误; - Wen_happiness
这个语句 "b[k]['d'].append("fb1")" 不是绑定语句吗? - Wen_happiness
@Wen_happiness:不会。它不会将任何对象绑定到任何名称上。这里是一些绑定语句:b = 1b 指向 1(整数对象)),import os as bb 指向 os 模块),def b(): passb 指向函数),class b: passb 指向类)。请参阅 Naming and Binding - jfs
显示剩余2条评论
1个回答

3
为了让代码在Windows和Linux上表现类似,请显式传递b参数:
Process(target=fb2, args=(k, b))

不同之处在于,在Linux中,默认使用fork,它将父进程的任何状态复制到子进程中。这就是为什么在子进程中可以看到fmt()内部所做的更改。

Windows默认使用spawn启动方法,仅部分地复制全局状态,例如导入时设置的值可见,但无法看到fmt()内部所做的更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接