Python中共享内存对进程池的影响

佚名 / 2024-08-24 / 原文

在Coding过程中,发现了共享内存会对进程池产生影响。

原始程序设计的思路是,在类中使用进程池创建不同的进程,这些进程间通过共享内存的方式控制一些变量。代码如下

import ctypes
from multiprocessing import Pool, Value


class Ex:
    def __init__(self, value):
        self.value = value

    def start(self):
        pool = Pool(1)
        pool.apply_async(self.p)

        pool.close()
        pool.join()

    def p(self):
        while True:
            print("Hello")

if __name__ == '__main__':
    value = Value(ctypes.c_bool, True)
    ex = Ex(value)
    ex.start()
    
# >>> 无输出

在该段代码中,创建了一个共享内存变量value,且实例化了一个类exex调用类中的start方法通过进程池创建了一个进程,该进程执行方法p。运行后发现,程序没有任何输出,但是当注释掉ex类构造方法中的self.value = value时,程序则可以正常运行。

import ctypes
from multiprocessing import Pool, Value


class Ex:
    def __init__(self, value):
        # self.value = value
        ...

    def start(self):
        pool = Pool(1)
        pool.apply_async(self.p)

        pool.close()
        pool.join()

    def p(self):
        while True:
            print("Hello")

if __name__ == '__main__':
    value = Value(ctypes.c_bool, True)
    ex = Ex(value)
    ex.start()
    
# >>> 循环输出'Hello'

初步判断是使用上文的共享内存方法与进程池会产生冲突。在StackOverflow上有人提出手动创建进程而不使用进程池,经尝试可以解决问题。

同时本文也找到了另一种解决方案,可采用manager对象创建共享内存,manager对象创建共享内存和直接创建共享内存的区别可查阅该文。简而言之便是,Value()速度快但是仅限于一台主机,Manager().Value()速度稍慢但可以跨平台使用。将程序改造后便可以正常运行。

import ctypes
from multiprocessing import Pool, Manager


class Ex:
    def __init__(self, value):
        self.value = value

    def start(self):
        pool = Pool(1)
        pool.apply_async(self.p)

        pool.close()
        pool.join()

    def p(self):
        while True:
            print("Hello")

if __name__ == '__main__':
    # 改造了共享内存创建方式
    manager = Manager()
    value = manager.Value(ctypes.c_bool, True)
    
    ex = Ex(value)
    ex.start()
    
# >>> 正常循环输出'Hello'