There is a socket related function call in my code, that function is from another module thus out of my control, the problem is that it blocks for hours occasionally, which is totally unacceptable, How can I limit the function execution time from my code? I guess the solution must utilize another thread.
相关问题
- how to define constructor for Python's new Nam
- streaming md5sum of contents of a large remote tar
- How to get the background from multiple images by
- Evil ctypes hack in python
- Correctly parse PDF paragraphs with Python
You don't have to use threads. You can use another process to do the blocking work, for instance, maybe using the subprocess module. If you want to share data structures between different parts of your program then Twisted is a great library for giving yourself control of this, and I'd recommend it if you care about blocking and expect to have this trouble a lot. The bad news with Twisted is you have to rewrite your code to avoid any blocking, and there is a fair learning curve.
You can use threads to avoid blocking, but I'd regard this as a last resort, since it exposes you to a whole world of pain. Read a good book on concurrency before even thinking about using threads in production, e.g. Jean Bacon's "Concurrent Systems". I work with a bunch of people who do really cool high performance stuff with threads, and we don't introduce threads into projects unless we really need them.
I prefer a context manager approach because it allows the execution of multiple python statements within a
with time_limit
statement. Because windows system does not haveSIGALARM
, a more portable and perhaps more straightforward method could be using aTimer
The key technique here is the use of
_thread.interrupt_main
to interrupt the main thread from the timer thread. One caveat is that the main thread does not always respond to theKeyboardInterrupt
raised by theTimer
quickly. For example,time.sleep()
calls a system function so aKeyboardInterrupt
will be handled after thesleep
call.Here's a Linux/OSX way to limit a function's running time. This is in case you don't want to use threads, and want your program to wait until the function ends, or the time limit expires.
I would usually prefer using a contextmanager as suggested by @josh-lee
But in case someone is interested in having this implemented as a decorator, here's an alternative.
Here's how it would look like:
And this is the
timeout.py
module:The output:
Notice that even if the
TimeoutError
is thrown, the decorated method will continue to run in a different thread. If you would also want this thread to be "stopped" see: Is there any way to kill a Thread in Python?An improvement on @rik.the.vik's answer would be to use the
with
statement to give the timeout function some syntactic sugar:Here's a timeout function I think I found via google and it works for me.
From: http://code.activestate.com/recipes/473878/