7

可能重复:
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
4

4 回答 4

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为全局变量(尽管我复制了整个代码以获得一个工作示例)

于 2013-01-18T20:08:27.717 回答
0

正如我在@BorrajaX 的回答中的评论中提到的那样,由于看起来您无论如何都受 POSIX 约束,因此您可以尝试使用名为 semaphore 的本机

于 2013-01-18T20:55:42.743 回答
0

您可以改用setlockDJ Bernstein 的 daemontools 中的程序:

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

于 2013-01-18T21:30:58.923 回答
-1

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

于 2013-01-18T19:54:33.247 回答