Подтвердить что ты не робот

Общесистемный мьютекс в Python на Linux

Есть ли простой способ иметь общесистемный мьютекс в Python на Linux? Под "общесистемным" я подразумеваю, что мьютекс будет использоваться группой процессов Python; это отличается от традиционного мьютекса, который используется группой потоков внутри одного и того же процесса.

ОБНОВЛЕНИЕ: Я не уверен, что пакет Python multiprocessing это то, что мне нужно. Например, я могу выполнить следующее в двух разных интерпретаторах:

from multiprocessing import Lock
L = Lock()
L.acquire()

Когда я выполняю эти команды одновременно в двух разных интерпретаторах, я хочу, чтобы один из них завис. Вместо этого ни один не висит; кажется, что они не получают тот же мьютекс.

4b9b3361

Ответ 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 и также предоставляет событие.