Python: fastenersで排他ロックを試す。

マルチプロセス環境において、複数のプロセスがよってたかって1つのファイルなどのリソースにアクセスするのを避けるために、プロセス間で排他ロックしたいときに使えるライブラリfastenersを試してみました。

環境はMac & Python 3.7.3 & fasteners 0.15です。

インストール

pipとか、仮想環境ならpipenvとかでインストールします。

 

サンプルプログラム

その1

 

7行目: lock = fasteners.InterProcessLock('locckFile')

ロックファイルを指定します。
リソースを共有する複数のプロセス同士は、このロックファイルの状態を通じて状態を把握します。

 

11行目: lock.acquire()

排他ロックを試みます。
排他ロックに成功すればそれ以降のプログラムが実行されます。ロックに失敗した場合は、別プロセスがロックを解放し、順番が回ってくるまでプログラムの実行がブロックされます。

 

18行目: lock.release()

ロックを開放します。開放し忘れるとデッドロックが発生するので要注意。

ロック中に実行したプログラムにエラーが発生しても、try-finallyのfinallyの中に書いておくと確実に実行されるので安心です。

 

14〜16行目:

ロック中に実行するプログラムです。

5秒間のスリープと、その前後の時刻を表示します。

 

サンプルの実行してみます。

ターミナルを2つ起動して、まず1つめのターミナルでサンプルプログラムを実行し、その直後2つめのターミナルで同プログラムを実行します。
手動で行ったのでタイム差は2秒ぐらいでしょうか。

1つめのターミナルの実行結果

2つめのターミナルでの実行結果

ターミナル1のプロセスが20:31:07にロック、5秒後の10:31:12ロック解除。
続けてターミナル2のプロセスが20:31:12にロック、5秒後の20:31:17にロック解除。

ターミナル1、ターミナル2の順番に、時間が重なり合わずにプログラムが動作しています。排他ロックがちゃんと働いていたということです。

 

その2

このように、withを使った記述も出来ます。
この記述方法は、acqire()とrelease()が不要で、withのブロック範囲が自動で排他ロックされます。
ロックの解除忘れ防止も出来て便利です。

 

その3

デコレータを使って、関数まるごと排他ロックの範囲に出来ます。

 

以上です。

参考にしたサイト

Python: fasteners の便利な排他ロックを試す

Pythonでプロセス間の排他ファイルアクセス

 

 

Leave a Comment

メールアドレスが公開されることはありません。

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください