Общесистемный мьютекс в Python на Linux
Есть ли простой способ иметь общесистемный мьютекс в Python на Linux? Под "общесистемным" я подразумеваю, что мьютекс будет использоваться группой процессов Python; это отличается от традиционного мьютекса, который используется группой потоков внутри одного и того же процесса.
ОБНОВЛЕНИЕ: Я не уверен, что пакет Python multiprocessing
это то, что мне нужно. Например, я могу выполнить следующее в двух разных интерпретаторах:
from multiprocessing import Lock
L = Lock()
L.acquire()
Когда я выполняю эти команды одновременно в двух разных интерпретаторах, я хочу, чтобы один из них завис. Вместо этого ни один не висит; кажется, что они не получают тот же мьютекс.
Ответы
Ответ 1
"Традиционный" ответ Unix - использовать блокировки файлов. Вы можете использовать lockf(3)
для блокировки разделов файла, чтобы другие процессы не могли его редактировать; очень распространенное злоупотребление заключается в том, чтобы использовать это как мьютекс между процессами. Эквивалент python fcntl.lockf.
Традиционно вы записываете PID процесса блокировки в файл блокировки, так что взаимоблокировки, связанные с процессами, умирающими при удерживании блокировки, являются идентифицируемыми и фиксируемыми.
Это дает вам то, что вы хотите, поскольку ваша блокировка находится в глобальном пространстве имен (файловой системе) и доступна для всех процессов. Этот подход также имеет преимущество, что в вашей блокировке могут участвовать программы, отличные от Python. Недостатком является то, что вам нужно место для записи этого файла блокировки; Кроме того, некоторые файловые системы на самом деле не блокируются правильно, поэтому существует риск, что он будет бесшумно отказываться от исключения. Вы выигрываете, теряете.
Ответ 2
В стандарте POSIX задаются семафоры между процессами, которые могут быть использованы для этой цели. http://linux.die.net/man/7/sem_overview
Модуль multiprocessing
в Python построен на этом API и других. В частности, multiprocessing.Lock
обеспечивает кросс-процесс "мьютекс". http://docs.python.org/library/multiprocessing.html#synchronization-between-processes
ИЗМЕНИТЬ, чтобы ответить на отредактированный вопрос:
В вашем доказательстве концепции каждый процесс строит a Lock()
. Таким образом, у вас есть два отдельных замка. Вот почему ни один процесс не ждет. Вам нужно будет использовать один и тот же замок между процессами. Раздел I, связанный с документацией multiprocessing
, объясняет, как это сделать.
Ответ 3
Попробуйте библиотеку ilock :
from ilock import ILock
with ILock('Unique lock name'):
# The code should be run as a system-wide single instance
...
Ответ 4
Для общесистемного мьютекса, который позволяет синхронизировать абсолютно отдельные процессы (т.е. INCLUDE Linux-процессы, которые НЕ принадлежат одному и тому же дереву процессов), просто используйте fcntl.flock. Я полагаю, что использование файла памяти в папке Linux/run/shm может ускорить выполнение.
Подробнее здесь.
Ответ 5
Просто, чтобы добавить его в список, есть библиотека posix_ipc, которая имеет класс Semaphore
.
Семафор со счетом 1 может использоваться как мьютекс.
Для завершения потокового трио библиотека SystemEvent использует posix_ipc
и также предоставляет событие.