摘要:简单记录一下windows下python3多进程使用属于类变量的共享变量、进程锁的问题

在windows下使用python3多进程时,如果使用multiprocessing.Process创建多进程, 要尤其注意需要将类变量中的共享变量、进程锁当成参数传递给multiprocessing.Process,不然可能导致多进程同时写入共享变量,结果失控。

import multiprocessing
from multiprocessing import freeze_support
from multiprocessing import Process,Lock


class Test:
    count = multiprocessing.Value('i', 0)
    lock = Lock()

    @classmethod
    def fun(cls):
        cls.lock.acquire()
        cls.count.value = cls.count.value + 1
        print('cls id: {}, cls.count id: {}, count: {}'.format(id(cls), id(cls.count), cls.count.value))
        cls.lock.release()

    @classmethod
    def test(cls):
        # 在windws下面创建进程时必须将共享变量count、进程锁lock 以参数的形式传递给Process函数,不然结果失控
        jobs = [Process(target=cls.fun) for i in range(100)]
        [j.start() for j in jobs]
        [j.join() for j in jobs]
        print('cls id: {}, cls.count id: {}, count: {}'.format(id(cls), id(cls.count), cls.count.value))

if __name__ == '__main__':
    freeze_support()
    Test.test()

运行结果如下:

windows下python3的多进程共享变量问题1.png

可以看到进程锁并没有起到作用,count值始终为1。但是相同的代码放在linux下面运行就没问题。

改成下面的代码就没问题了。



import multiprocessing
from multiprocessing import freeze_support
from multiprocessing import Process,Lock


class Test:
    count = multiprocessing.Value('i', 0)
    lock = Lock()

    @classmethod
    def fun(cls, lock, count):
        lock.acquire()
        count.value = count.value + 1
        print('cls id: {}, count id: {}, count: {}'.format(id(cls), id(count), count.value))
        lock.release()

    @classmethod
    def test(cls):
        # 在windws下面创建进程时必须将共享变量count、进程锁lock 以参数的形式传递给Process函数,不然结果失控
        jobs = [Process(target=cls.fun, args=(cls.lock, cls.count)) for i in range(100)]
        [j.start() for j in jobs]
        [j.join() for j in jobs]
        print('cls id: {}, count id: {}, count: {}'.format(id(cls), id(cls.count), cls.count.value))

if __name__ == '__main__':
    freeze_support()
    Test.test()

这里大概说一下,windows下的多进程和linux下多进程是两回事。具体啥区别我有点忘了,但是使用python时在windows下面用多线程、linux下面用多进程准没错的。

有兴趣可以参考:python:windows和linux下multiprocessing模块创建进程的区别