7

重複の可能性:
Python: プログラムの単一インスタンス

ジョブの完了にランチャー間隔よりも長い時間がかかる場合、cron ジョブが同時インスタンスを実行しないようにする必要があります。これを実現するために群れの概念を使用しようとしていますが、fcntl モジュールが期待どおりに動作していません。

これが2つの同時インスタンスを防ぐために機能する理由を誰か教えてください:

import sys
import time
import fcntl

file_path = '/var/lock/test.py'
file_handle = open(file_path, 'w')

try:
    fcntl.lockf(file_handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
    print 'no other instance is running'
    for i in range(5):
        time.sleep(1)
        print i + 1

except IOError:
    print 'another instance is running exiting now'
    sys.exit(0)

そして、これが機能しない理由:

import sys
import time
import fcntl

def file_is_locked(file_path):
    file_handle = open(file_path, 'w')
    try:
        fcntl.lockf(file_handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
        return False
    except IOError:
        return True

file_path = '/var/lock/test.py'

if file_is_locked(file_path):
    print 'another instance is running exiting now'
    sys.exit(0)
else:
    print 'no other instance is running'
    for i in range(5):
        time.sleep(1)
        print i + 1
4

4 に答える 4

7

私の謙虚な意見(私は完全に間違っているかもしれませんが)はfile_handle、関数にローカルであるため(2番目の場合)、関数が実行されると破棄されます。

次のコードは期待どおりに機能しているようです。

#!/usr/bin/env python
#http://stackoverflow.com/questions/14406562/prevent-running-concurrent-instances-of-a-python-script

import sys
import time
import fcntl

file_handle = None

def file_is_locked(file_path):
    global file_handle 
    file_handle= open(file_path, 'w')
    try:
        fcntl.lockf(file_handle, fcntl.LOCK_EX | fcntl.LOCK_NB)
        return False
    except IOError:
        return True

file_path = '/var/lock/test.py'

if file_is_locked(file_path):
    print 'another instance is running exiting now'
    sys.exit(0)
else:
    print 'no other instance is running'
    for i in range(5):
        time.sleep(1)
        print i + 1

file_handle私が行ったのはグローバル変数として設定することだけであることに注意してください(実際の例を示すためにコード全体をコピーしましたが)

于 2013-01-18T20:08:27.717 に答える
0

@BorrajaX の回答に関するコメントで述べたように、とにかく POSIX にバインドされているように見えるので、ネイティブの名前付き semaphoreを使用してみてください。

于 2013-01-18T20:55:42.743 に答える
0

setlock代わりに、DJ Bernstein の daemontoolsのプログラムを使用できます。

http://cr.yp.to/daemontools/setlock.html

于 2013-01-18T21:30:58.923 に答える
-1

最も簡単な方法は、スクリプトの開始時にファイル /tmp/scriptlock を作成し、作業を行う前にそのファイルが存在するかどうかを確認することです。処理の最後にロックファイルが削除されていることを確認してください。

于 2013-01-18T19:54:33.247 に答える