防止运行python脚本的并发实例

时间:2013-01-18 19:50:10

标签: python cron fcntl

  

可能重复:
  Python: single instance of program

当作业需要比启动程序间隔更长时间完成时,我需要阻止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

4 个答案:

答案 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程序代替:

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

答案 3 :(得分:-1)

最简单的方法是在脚本开头创建一个文件/ tmp / scriptlock,并在开始工作之前检查该文件是否存在。确保在处理结束时删除了锁定文件。