开发者

python, break function after 3 seconds

开发者 https://www.devze.com 2023-03-19 06:02 出处:网络
Sometimes, my function will h开发者_StackOverflow中文版ang. If the function is longer than 3 seconds.

Sometimes, my function will h开发者_StackOverflow中文版ang. If the function is longer than 3 seconds. I want to quit from this function, how to do this?

Thanks


Well, you should probably just figure out why it is hanging. If it is taking a long time to do the work then perhaps you could be doing something more efficiently. If it needs more than three seconds than how will breaking in the middle help you? The assumption is that the work actually needs to be done.

What call is hanging? If you don't own the code to the call that is hanging you're SOL unless you run it on another thread and create a timer to watch it.

This sounds to me like it may be a case of trying to find an answer to the wrong question, but perhaps you are waiting on a connection or some operation that should have a timeout period. With the information (or lack thereof) you have given us it is impossible to tell which is true. How about posting some code so that we are able to give a more definitive answer?


I had to do to something like that, too. I whipped up a module that provides a decorator to limit the runtime of a function:

import logging
import signal
from functools import wraps

MODULELOG = logging.getLogger(__name__)

class Timeout(Exception):
    """The timeout handler was invoked"""

def _timeouthandler(signum, frame):
    """This function is called by SIGALRM"""
    MODULELOG.info('Invoking the timeout')
    raise Timeout

def timeout(seconds):
    """Decorate a function to set a timeout on its execution"""
    def wrap(func):
        """Wrap a timer around the given function"""
        @wraps(func)
        def inner(*args, **kwargs):
            """Set an execution timer, execute the wrapped function,
            then clear the timer."""
            MODULELOG.debug('setting an alarm for %d seconds on %s' % (seconds, func))
            oldsignal = signal.signal(signal.SIGALRM, _timeouthandler)
            signal.alarm(seconds)
            try:
                return func(*args, **kwargs)
            finally:
                MODULELOG.debug('clearing the timer on %s' % func)
                signal.alarm(0)
                signal.signal(signal.SIGALRM, oldsignal)
        return inner
    return wrap

I use it like:

@limits.timeout(300)
def dosomething(args): ...

In my case, dosomething was calling an external program which would periodically hang and I wanted to be able to cleanly exit whenever that happened.


I was able to set a timeout on input by using the select module.
You should be able to set your input type appropriately.

i,o,e = select.select([sys.stdin],[],[],5)

This will listen for input for 5 seconds before moving on.

0

精彩评论

暂无评论...
验证码 换一张
取 消