12

У меня есть программа, где multiprocessingВозможно ли установить приоритет блокировки?

  • один процесс добавляет элементы в общий список (multiprocessing.Manager().list())
  • несколько других процессов потребить эти элементы из этого списка (и удалить их); они запускаются до тех пор, пока в списке что-то не обработает, и вышеописанный процесс все еще добавляет в список.

Я добавил блокировку (через multiprocessing.Lock()) при добавлении в список или удаление его. Поскольку существует один «фидерный» процесс и несколько (10-40) «потребительских», все конкурирующие за блокировку, и что потребительские процессы бывают быстрыми, я получаю процесс «фидера», который с трудом приобретает блокировку.

Есть ли понятие «приоритет» при приобретении замка? Я бы хотел, чтобы процесс «фидера» приобрел его с большим приоритетом, чем остальные.

В настоящее время я смягчил проблему, когда «потребительские» процессы ждут случайного времени, прежде чем пытаться получить блокировку, пока процесс «фидер» (когда он заканчивается, устанавливает флаг). Это обходное решение, которое работает, но оно уродливое и вряд ли эффективно (у меня есть процессы, ожидающие random.random()*n секунд, где n - это количество процессов. Это полностью заполненный номер, возможно, неправильный).

+0

как понятие "очереди" реализуется? Вы просто добавляете процессы в список, когда они приходят за блокировкой? –

+0

@ Ev.Kounis: да, это «multiprocessing.Manager(). List()», как я упоминал в вопросе (это не «multiprocessing.Queue()») – WoJ

+0

Я не имею в виду список в какие элементы добавляются и извлекаются из, я имею в виду структуру (список?), которая отслеживает приоритет процессов. –

ответ

0

Это не идеально, но оно должно работать:

В "фидер":

feeder_lock_object.lock() 
consumer_lock_object.lock() 
try: 
    ... 
finally: 
    feeder_lock_object.release() 
    consumer_lock_object.release() 

В "потребитель":

while True: 
    with consumer_lock_object: 
     if feeder_lock_object.is_locked: 
      continue 
     ... 

Но я думаю, что это будет лучше, если вы будете использовать Очередь.

Если вы используете этот метод, будьте осторожны с тем, как вы реализуете объект блокировки. Вы должны инициализировать пул с помощью функции инициализатора, которая создает эти объекты блокировки в качестве глобальных параметров. См. this.

0

Вместо того чтобы пытаться изменить приоритет блокировки, попробуйте сами изменить приоритет процесса, так что фидер имеет более высокий приоритет, чем потребитель. Обходной путь, который вы использовали, в основном имитирует это, но с меньшей эффективностью.

Чтобы изменить приоритет процесса,

В Unix: использование os.setpriority()

Направить docs

На окнах, используйте модуль партии psutil третьего.

См. this thread и Psutil Docs.

1

Обеспечить получение Фидером блокировки блокировки и неблокирование потребителя.
Так что для фидера:

try: 
    with my_lock.acquire(): #locks block by default 
     do stuff 
finally: 
    my_lock.release() 

И потребители:

while True: 
    try: 
     locked = my_lock.acquire(blocking=False) 
     if locked: 
     do stuff 
    finally: 
     if locked: 
     my_lock.release() 
    time.sleep(seconds=10) 
Смежные вопросы