Возможно ли установить приоритет блокировки?

У меня есть программа multiprocessing, где

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

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

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

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

Ответ 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)

Ответ 2

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

В "фидере":

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
        ...

Но я думаю, что будет лучше, когда вы будете использовать Queue.

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

Ответ 3

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

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

В Unix: используйте os.setpriority()

Обратитесь docs

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

Обратитесь к этой теме и Psutil Docs.