问题
- 发现再创建子进程时调用类,发现通过构造函数给类所在文档的全局变量赋值,在子进程执行时并未赋值成功
结论原因
- 全局变量的赋值在创建子进程时不能放在构造方法中,会没有办法赋值
- 使用spawn模式创建,只会继承部分必要资源,当时的全局变量的值并不是必要资源部,并不在资源继承中;
- 在构造方法中赋值时,子进程的空间并没有被完全独立,全局变量的赋值是给主进程的内存空间中的这个变量所赋的值
解决方案
- 在启动方法中进行
- 也可以通过单独的方法,将全局变量赋值和启动方法再次包装(会让代码更整洁些)
def start_def(self, dic, lis):
"""
给全局变量赋值方法
:param dic:
:param lis:
:return:
"""
global DIC
global LIS
DIC = dic
LIS = lis
self.fun1()
测试代码
import time
from multiprocessing import Process, Manager
import fun1
from fun1 import FunC
class MMain:
def start_main(self):
manager = Manager()
dic = manager.dict()
l = manager.list(range(5))
process_list = []
for i in range(10):
print("启动进程", i)
p = Process(target=FunC(i, dic, l).fun1, args=())
p.start()
process_list.append(p)
print("启动完成")
print(fun1.LIS) # 如果是给主进程内的全局变量赋值,这里就能打印出值
for res in process_list:
res.join()
print("打印结果")
print(dic)
print(l)
if __name__ == '__main__':
MMain().start_main()
import time
DIC = {}
LIS = []
class FunC:
def __init__(self, index, dic, lis):
global DIC
global LIS
DIC = dic
LIS = lis
self.index = index
def fun1(self):
global DIC
global LIS
print(LIS)
DIC[self.index] = 'a'
DIC['2'] = 'b'
LIS.append(self.index) # [0,1,2,3,4,0,1,2,3,4,5,6,7,8,9]
time.sleep(self.index)
print("进程", self.index, "结束")
# print(l)
打印结果
启动进程 0
启动进程 1
启动进程 2
启动进程 3
启动进程 4
启动进程 5
启动进程 6
启动进程 7
启动进程 8
启动进程 9
启动完成
[0, 1, 2, 3, 4]
[]
[]
[]
进程 0 结束
[]
进程 1 结束
[]
[]
[]
[]
[]
[]
进程 2 结束
进程 3 结束
进程 4 结束
进程 5 结束
进程 6 结束
进程 7 结束
进程 8 结束
进程 9 结束
打印结果
{}
[0, 1, 2, 3, 4]