Python多进程时子进程的全局变量问题

问题

  • 发现再创建子进程时调用类,发现通过构造函数给类所在文档的全局变量赋值,在子进程执行时并未赋值成功

结论原因

  • 全局变量的赋值在创建子进程时不能放在构造方法中,会没有办法赋值
  • 使用spawn模式创建,只会继承部分必要资源,当时的全局变量的值并不是必要资源部,并不在资源继承中;
  • 在构造方法中赋值时,子进程的空间并没有被完全独立,全局变量的赋值是给主进程的内存空间中的这个变量所赋的值

解决方案

  1. 在启动方法中进行
  2. 也可以通过单独的方法,将全局变量赋值和启动方法再次包装(会让代码更整洁些)
  • 在测试代码中加入方法(解决方案2)
    def start_def(self, dic, lis):
        """
        给全局变量赋值方法
        :param dic:
        :param lis:
        :return:
        """
        global DIC
        global LIS
        DIC = dic
        LIS = lis
        self.fun1()

测试代码

  • main.py
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()

  • fun1.py
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]


你可能感兴趣的:(Python多进程时子进程的全局变量问题)