Fari

python:多进程共享复杂的可写对象

本来想用该方法共享一个模型的,一个进程用于收集训练数据,一个进程用于训练,但是仍然不行。但基本的进程共享内存空间对象还是可以的:

from multiprocessing import Process
from multiprocessing.managers import BaseManager

# 第一步:定义需要共享的类
class Data:
    """
    该对象处于共享内存中,其内部属性(即使是自定义对象)也是在共享内存中
    """
    def __init__(self, n=0):
        self.num = n

    def add(self, i):
        # 注:该操作进程不安全,需要加锁才能保证安全
        self.num += i

    def get_num(self):
        return self.num

# 第二步:创建一个继承 BaseManager 的类,内容可以为空
class MyManger(BaseManager):
    ...

# 第三步:注册共享类
MyManger.register("Data", Data)

if __name__ == '__main__':
    # 第四步:创建自定义Manager对象并启动
    manager = MyManger()
    manager.start()

    # 第五步:获取共享对象的引用,该对象已经位于共享内存中,但它其实是一个代理对象,其类型为 AutoProxy[Data],所以你不能直接获取其 num 属性
    d = manager.Data()

    p1 = Process(target=d.add, args=(1,))
    p2 = Process(target=d.add, args=(1,))

    p1.start()
    p2.start()

    p1.join()
    p2.join()

    # 注:再次强调,由于 d 是一个代理对象,所以你不能直接通过 d.num 获取num的值
    print(d.get_num())  # 2,两个进程各自加1

python中进程池要使用 Semaphore 时,需要使用 multiprocessing.Manager().Semaphore() 对象,而不是 multiprocessing.Semaphore() 对象,相应的 Lock、Value也是

def task(sem, v):  sem.acquire()  print(v.get())  sema.release()def main():  manager = multiprocessing.Manager()  pool = multiprocessing.Pool(10)    sem = manager.Semaphore(3)  v = manager.Value(dict, {'ans': 2, 'good': 3, 'bad': 1, 'parms': [1, 2, 3, 4]}) # 第一个参数表示类型,第二个参数为数据  pool.apply_async(func=task, args=(sem, v))
Tags: