当作业需要比启动程序间隔更长时间完成时,我需要阻止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
答案 0 :(得分:7)
我的拙见(虽然我可能完全错了)是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
设置为全局变量(尽管我复制了整个代码以获得一个工作示例)
答案 1 :(得分:0)
正如我在@ BorrajaX的回答中提到的那样,因为看起来你是POSIX绑定的,你可以尝试使用native named semaphore。
答案 2 :(得分:0)
你可以使用D. J. Bernstein的daemontools的setlock
程序代替:
答案 3 :(得分:-1)
最简单的方法是在脚本开头创建一个文件/ tmp / scriptlock,并在开始工作之前检查该文件是否存在。确保在处理结束时删除了锁定文件。