fcntl.flock-如何实现超时? [英] fcntl.flock - how to implement a timeout?

查看:388
本文介绍了fcntl.flock-如何实现超时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用python 2.7

I am using python 2.7

我想围绕fcntl.flock()创建一个包装函数,该函数将在设置的时间间隔后超时:

I want to create a wrapper function around fcntl.flock() that will timeout after a set interval:

wrapper_function(timeout):

我尝试调用另一个线程并使用thread.join(timeout),但似乎fcntl.flock()继续阻塞:

I've tried calling on another thread and using thread.join(timeout) but it seems that fcntl.flock() continues blocking:

def GetLock(self, timeout):
    """Returns true if lock is aquired, false if lock is already in use"""
    self.__lock_file = open('proc_lock', 'w')

    def GetLockOrTimeOut():
        print 'ProcessLock: Acquiring Lock'            
        fcntl.flock(self.__lock_file.fileno(), fcntl.LOCK_EX)
        print 'ProcessLock: Lock Acquired'

    thread = threading.Thread(target=GetLockOrTimeOut)
    thread.start()
    thread.join(timeout)

    if thread.isAlive():
        print 'GetLock timed out'
        return False
    else:
        return True

我已经研究了终止线程的解决方案,最流行的解决方案似乎是将threading.thread子类化,并添加了在线程中引发异常的功能.但是,我遇到了一个链接,该链接说该方法不适用于本机调用,我很确定fcntl.flock ()正在调用本机函数.有建议吗?

I've looked into solutions for terminating threads, the most popular solution seems to be sub-classing threading.thread and adding a feature to raise an exception in the thread. However, I came across a link that says this method will not work with native calls, which I am pretty sure fcntl.flock() is calling a native function. Suggestions?

上下文:我正在使用文件锁来创建一个单实例应用程序,但我不希望该应用程序的第二个实例随处挂起并挂起,直到第一个实例终止.

Context: I am using a file-lock to create a single instance application but I don't want a second instance of the application to sit around and hang until the first instance terminates.

推荐答案

系统调用的超时是通过信号完成的.发生信号时,大多数阻塞系统调用都会以EINTR返回,因此您可以使用alarm来实现超时.

Timeouts for system calls are done with signals. Most blocking system calls return with EINTR when a signal happens, so you can use alarm to implement timeouts.

这是一个上下文管理器,可用于大多数系统调用,如果花费的时间太长,则会导致从阻塞的系统调用中引发IOError.

Here's a context manager that works with most system calls, causing IOError to be raised from a blocking system call if it takes too long.

import signal, errno
from contextlib import contextmanager
import fcntl

@contextmanager
def timeout(seconds):
    def timeout_handler(signum, frame):
        pass

    original_handler = signal.signal(signal.SIGALRM, timeout_handler)

    try:
        signal.alarm(seconds)
        yield
    finally:
        signal.alarm(0)
        signal.signal(signal.SIGALRM, original_handler)

with timeout(1):
    f = open("test.lck", "w")
    try:
        fcntl.flock(f.fileno(), fcntl.LOCK_EX)
    except IOError, e:
        if e.errno != errno.EINTR:
            raise e
        print "Lock timed out"

这篇关于fcntl.flock-如何实现超时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆