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: