2

python | 多进程共享类对象

 1 year ago
source link: https://benpaodewoniu.github.io/2022/10/14/python178/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

另外,我对这一章节理解的不够深刻。。。

多进程通信可以用

  • Manager().Value()

进程池通信可以使用

  • Manager().dict()

用 Manager().dict()

用 BaseManager 进行共享

import os
import time
from concurrent.futures.process import ProcessPoolExecutor
from multiprocessing import Manager
from multiprocessing.managers import BaseManager

l = Manager().Lock()


class Item:
def __init__(self):
self.H = 1

def add(self):
print(f"Item {os.getpid()}")
self.H += 1

def see(self):
print(f"Item {os.getpid()}")


def ChangeItem(v):
try:
# with l:
print(f"ChangeItem {os.getpid()}")
# v.H += 1
v.add()
v.see()
except Exception as e:
print(e)


if __name__ == '__main__':
print(f"{os.getpid()}")
# v = Value('I', Item())
BM = BaseManager()
BM.register("Item", Item)
BM.start()
I = BM.Item()

p = ProcessPoolExecutor(max_workers=5)
for i in range(10):
p.submit(ChangeItem, I)
42926
ChangeItem 42936
ChangeItem 42938
ChangeItem 42937
ChangeItem 42939
Item 42934
Item 42934
Item 42934
Item 42934
Item 42934
Item 42934
ChangeItem 42940
Item 42934
Item 42934
ChangeItem 42936
Item 42934
Item 42934
ChangeItem 42938
Item 42934
Item 42934
ChangeItem 42937
ChangeItem 42939
Item 42934
ChangeItem 42940
Item 42934
Item 42934
Item 42934
Item 42934
Item 42934
Item 42934
Item 42934

可以看出,BaseManager 下面的实例有自己单独的进程。

但是,这样做的实例,只能调用实例方法,调用不了属性。

import os
import time
from concurrent.futures.process import ProcessPoolExecutor
from multiprocessing import Manager
from multiprocessing.managers import BaseManager

l = Manager().Lock()


class Item:
def __init__(self):
self.H = 1

def add(self):
print(f"Item {os.getpid()}")
self.H += 1

def see(self):
print(f"Item {os.getpid()}")


def ChangeItem(v):
try:
# with l:
print(f"ChangeItem {os.getpid()}")
v.H += 1
# v.add()
# v.see()
except Exception as e:
print(e)


if __name__ == '__main__':
print(f"{os.getpid()}")
# v = Value('I', Item())
BM = BaseManager()
BM.register("Item", Item)
BM.start()
I = BM.Item()

p = ProcessPoolExecutor(max_workers=5)
for i in range(10):
p.submit(ChangeItem, I)
'AutoProxy[Item]' object has no attribute 'H'

具体原因可以查看

The Proxy objects used by multiprocessing.BaseManager and its sub-classes normally only expose methods from the objects they’re referring to, not attributes. Now, there is multiprocessing.Manager().Namespace, which provides a Proxy sub-class that does provide access to attributes, rather than methods. We can create our own Proxy type which inherits from that, which enables access to all our attributes, as well as access to our b function

但是,上述方法属于 python2.7 版本的用法,在 python3 中并不适用,所以,只能留给后面更新了。

这里如果想要访问属性的话,就用 getset 方法吧。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK