Общий принцип многопроцессорности. Блокировка в python3 - PullRequest
0 голосов
/ 02 февраля 2019

Возможно ли иметь общий диктат Locks в python3?Мне нужно несколько блокировок, потому что я хочу защитить часть общих ресурсов.Каждый ресурс получает блокировку:

manager = multiprocessing.Manager()

locks = manager.dict({key : manager.Lock() for key in range(100)})
shared_resource = manager.dict({key : SomeClass() for key in range(100)})

# later in a multi-processed function
def foo(key):
  # ...
  locks[key].acquire()
  shared_resource[key] = ...
  locks[key].release()
  # ...

Этот игрушечный пример потерпит неудачу с:

multiprocessing.managers.RemoteError: 
---------------------------------------------------------------------------
Unserializable message: ('#RETURN', <unlocked _thread.lock object at 0x7f9a4c9dc468>)

Есть идеи, как обойти эту проблему?Я мог бы использовать условные переменные?Или как бы вы защитили список ресурсов?

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

Хорошо, похоже, что это ошибка с ptyhon3.5.

С python3.6 это работает как шарм.

0 голосов
/ 02 февраля 2019

Я уверен, что это возможно.Я не получаю сообщение об ошибке при запуске этого кода ... Я просто заменил SomeClass на 'x'.Так что, возможно, там есть проблема.Кроме того, использование диспетчера контекста для получения и снятия блокировки - это хорошая маленькая абстракция ...

manager = multiprocessing.Manager()
locks = {key : manager.Lock() for key in range(100)}
shared_resource = {key : 'x' for key in range(100)}

# later in a multi-processed function
def foo(key):
   # ...
  with locks[key]:
  shared_resource[key] = 'xoyo'

if __name__ == '__main__':
    p = Process(target=foo, args=(1,))
    p.start()
    p = Process(target=foo, args=(1,))
    p.start()
    p = Process(target=foo, args=(1,))
    p.start()
    p.join()
...