GNU/Linux >> Linux の 問題 >  >> Linux

Linux 上の Python でのシステム全体のミューテックス

ilock ライブラリを試す:

from ilock import ILock

with ILock('Unique lock name'):
    # The code should be run as a system-wide single instance
    ...

「伝統的な」Unix の答えは、ファイル ロックを使用することです。 lockf(3) を使用できます ファイルのセクションをロックして、他のプロセスが編集できないようにする。非常に一般的な乱用は、これをプロセス間のミューテックスとして使用することです。 Python に相当するものは fcntl.lockf です。

伝統的に、ロックしているプロセスの PID をロック ファイルに書き込むことで、ロックを保持している間にプロセスが停止することによるデッドロックを識別および修正できるようにします。

ロックはグローバル名前空間 (ファイルシステム) にあり、すべてのプロセスからアクセスできるため、これで必要なものが得られます。このアプローチには、Python 以外のプログラムがロックに参加できるという利点もあります。欠点は、このロック ファイルを保存する場所が必要なことです。また、一部のファイルシステムは実際には正しくロックされないため、黙って除外に失敗するリスクがあります。勝つものもあれば、失うものもあります。


私の回答は他の回答と重複していますが、人々がコピペできる何かを追加するために、私はよくこのようなことをします.

class Locker:
    def __enter__ (self):
        self.fp = open("./lockfile.lck")
        fcntl.flock(self.fp.fileno(), fcntl.LOCK_EX)

    def __exit__ (self, _type, value, tb):
        fcntl.flock(self.fp.fileno(), fcntl.LOCK_UN)
        self.fp.close()

そして、それを次のように使用します:

print("waiting for lock")
with Locker():
    print("obtained lock")
    time.sleep(5.0)

テストするには、touch lockfile.lck を実行します 次に、上記のコードを 2 つ以上の異なる端末で (同じディレクトリから) 実行します。

更新:smwikipedia は、私のソリューションが UNIX 固有であると述べています。最近、ポータブル バージョンが必要になり、ランダムな github プロジェクトからアイデアを得て、次のように思いつきました。 seek() 呼び出しが必要かどうかはわかりませんが、Windows API がファイル内の特定の位置をロックしているため、存在します。ロック以外の目的でファイルを使用していない場合は、おそらくシークを削除できます。

if os.name == "nt":
    import msvcrt

    def portable_lock(fp):
        fp.seek(0)
        msvcrt.locking(fp.fileno(), msvcrt.LK_LOCK, 1)

    def portable_unlock(fp):
        fp.seek(0)
        msvcrt.locking(fp.fileno(), msvcrt.LK_UNLCK, 1)
else:
    import fcntl

    def portable_lock(fp):
        fcntl.flock(fp.fileno(), fcntl.LOCK_EX)

    def portable_unlock(fp):
        fcntl.flock(fp.fileno(), fcntl.LOCK_UN)


class Locker:
    def __enter__(self):
        self.fp = open("./lockfile.lck")
        portable_lock(self.fp)

    def __exit__(self, _type, value, tb):
        portable_unlock(self.fp)
        self.fp.close()

POSIX 標準では、この目的で使用できるプロセス間セマフォが指定されています。 http://linux.die.net/man/7/sem_overview

multiprocessing Python のモジュールは、この API などに基づいて構築されています。特に、multiprocessing.Lock クロスプロセスの「ミューテックス」を提供します。 http://docs.python.org/library/multiprocessing.html#synchronization-between-processes

編集 編集した質問に回答するには:

概念実証では、各プロセスが Lock() を構築しています .したがって、2 つの個別のロックがあります。そのため、どちらのプロセスも待機しません。プロセス間で同じロックを共有する必要があります。 multiprocessing でリンクしたセクション ドキュメンテーションでその方法を説明しています。


Linux
  1. LinuxでのPythonany()関数

  2. RockyLinux8にPython3.10をインストールする方法

  3. Linux スレッド同期に C Mutex ロックの例を使用する方法

  1. LinuxにPythonをインストールする方法

  2. RockyLinux8にPythonをインストールする

  3. Linux 上の Python で export を使用する方法

  1. Linux –ライブラリ関数への呼び出しのシステム全体の監視?

  2. Linux への Python プログラムのインストール

  3. Linuxでpythonファイルを実行する方法