我无法正确使用SyncManager.Lock
。我读了official doc,但它没有提供任何有效的例子。我也不知道如何正确使用SyncManager.Event
。
下面是说明我的问题的最小代码。 client1
和client2
都需要更新共享对象Struct
。但是,我希望client1
首先获取锁定,更新Struct
,然后将控制权传递给client2
。如果按原样运行下面的代码,print
语句就会混淆。
import multiprocessing as mp
from multiprocessing.managers import SyncManager
import time
class Struct:
def __init__(self):
self.a = []
def update(self, x, y):
self.a.append(x ** 2)
def get(self):
return self.a
class Server(SyncManager):
pass
global_S = Struct()
Server.register('Struct', lambda: global_S)
def server_run():
print('Server starting ...')
manager = Server(('localhost', 8080), authkey=b'none')
manager.get_server().serve_forever()
def client_run(name, x, y, wait):
server_proc = Server(('localhost', 8080), authkey=b'none')
server_proc.connect()
S = server_proc.Struct()
with server_proc.Lock():
for i in range(5):
S.update(x+i, y+i)
print(name, S.get())
time.sleep(wait)
server = mp.Process(target=server_run)
server.daemon = True
client1 = mp.Process(target=client_run, args=('c1', 3,7, 1))
client2 = mp.Process(target=client_run, args=('c2', 100,120, .6))
server.start()
time.sleep(0.3) # wait for server to spawn up
client1.start()
time.sleep(0.3)
client2.start()
client1.join()
client2.join()
示例输出:
Server starting ...
c1 [9]
c2 [9, 10000]
c2 [9, 10000, 10201]
c1 [9, 10000, 10201, 16]
c2 [9, 10000, 10201, 16, 10404]
c1 [9, 10000, 10201, 16, 10404, 25]
c2 [9, 10000, 10201, 16, 10404, 25, 10609]
c2 [9, 10000, 10201, 16, 10404, 25, 10609, 10816]
c1 [9, 10000, 10201, 16, 10404, 25, 10609, 10816, 36]
c1 [9, 10000, 10201, 16, 10404, 25, 10609, 10816, 36, 49]
答案 0 :(得分:2)
我想出了一个解决方法。由于以下原因,请勿使用内置SyncManager.Lock()
:
解决方案是注册您自己的锁管理器:
from multiprocessing.managers import BaseManager, AcquirerProxy
global_lock = mp.Lock()
def get_lock():
print('getting global_lock')
return global_lock
Server.register('Lock', get_lock, AcquirerProxy)