Возможно ли установить приоритет блокировки?
У меня есть программа 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.