2013-01-18 64 views
6

可能重複:
Python: single instance of program防止運行一個python腳本的併發實例

我需要防止cron作業運行併發的情況下,當工作需要更長的時間比發射完成間隔。我正在嘗試使用flock概念來實現這一點,但fcntl模塊的行爲並不像我期望的那樣。

誰能告訴我爲什麼這個工程,以防止兩個併發實例:

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 
+1

http://stackoverflow.com/questions/380870/python-single-instance-of-program的可能DUP。其中還包括一個名爲[tendo]的圖書館(http://pypi.python.org/pypi/tendo),用於處理所有煩人的跨平臺問題。當然它不回答「爲什麼工作而不是B?」問題,但它確實解決了根本問題「我應該怎麼做?」 – abarnert

回答

6

我的愚見(雖然我可能完全錯誤)是file_handle是函數的本地(在第二種情況下),因此,它在函數完成後被破壞。

下面的代碼似乎按預期方式工作:

#!/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爲全局變量(雖然我複製了整個代碼有一個工作示例)

+0

好的。所以問題在於,在第一個實例完成運行之前,句柄會被垃圾收集,因此即使它還沒有完成,也會釋放鎖。似乎是一個很好的理由使用和反對此。然後,您可以使用相同的代碼來防止跨越任意數量的循環,線程或進程併發運行。然後再次,你可以嘗試http://stackoverflow.com/questions/2798727/named-semaphores-in-python –

-1

最簡單的方法是創建一個文件/ tmp/scriptlock在腳本開始時檢查文件是否存在,然後再開始工作。確保在處理結束時刪除鎖定文件。

+0

如果你這樣做,確保你使用Python的tempfile模塊來避免競爭條件 – limscoder

+1

這與OP所做的很相似,他問的問題是「爲什麼這些不同?不是,「我怎麼能這樣做?」 –

+0

即使他們不使用fcntl,我也可以採用其他方式避免競爭條件。 – tponthieux

0

正如我在@ BorrajaX的回答中提到的那樣,因爲無論如何它看起來像是POSIX綁定的,您可以嘗試使用native named semaphore

相關問題