类中使用multiprocess.Pool.map时属性不更新及异常输出原因咨询
问题核心原因:多进程内存空间隔离
为什么主进程最终打印a.count为0
Python的multiprocessing模块创建的子进程拥有完全独立的虚拟地址空间,和父进程的内存不共享,结合Pool.map的执行逻辑,具体过程如下:
- 调用
Pool(processes=4)时,会提前创建4个独立的工作子进程,子进程会复制父进程的内存快照(Unix下fork机制)或重新初始化执行环境(Windows下spawn机制),此时子进程拿到的Acc类实例a的副本初始count值都是0。 - 执行
pool.map(self.run, [1]*30)时,Python需要把绑定方法self.run序列化(pickle)后传递给子进程,子进程反序列化后得到的是原实例的独立副本,所有对self.count的修改都只会作用在子进程自己的副本上,完全不会影响主进程里的原实例a。 - 所有任务执行完成后,主进程里的
a.count从来没有被修改过,所以最终打印结果是初始值0。
为什么子进程内输出混杂大量0和1
该现象是多进程调度+输出无同步共同导致的:
- 4个工作进程会平分30个任务,每个进程的
count值是独立累加的,互不影响。 - 多进程没有对标准输出加锁,多个进程同时向终端打印内容时,会出现输出乱序、内容拼接的情况,也就是你看到的
00、10、换行混乱等现象。 - 如果你观察到的输出只有0和1,通常是因为绑定方法序列化时每次都会拉取主进程中未修改的原实例状态,主进程
count始终为0,所以每个子任务拿到的副本初始值都是0。
内容的提问来源于stack exchange,提问作者ZheLiu
相关产品推荐
相关产品推荐

