This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2011年06月25日 14:49 by mouad, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| operation_timeout.patch | mouad, 2011年06月25日 15:00 | Add a helper method to make sure that an operation will not last more than a given timeout. | review | |
| Messages (6) | |||
|---|---|---|---|
| msg139075 - (view) | Author: mouad (mouad) * | Date: 2011年06月25日 14:49 | |
While working on issue #12157 [http://bugs.python.org/issue12157], I needed a function that make sure that an operation will not hang forever, for this reason i have create this helper function that support the context manager protocol and accept a timeout as an argument and raise an IOError if the operation didn't terminate before that timeout. |
|||
| msg139091 - (view) | Author: Charles-François Natali (neologix) * (Python committer) | Date: 2011年06月25日 15:59 | |
It's a little bit more complicated than that: - signals and threads don't mix well together - this will make syscalls fail with EINTR - the old SIGALRM handler is lost - etc In short, don't use signals. I'm not sure there's a reliable way to write such a general-purpose wrapper (usually one can use select() with a timeout or spawn a subprocess and use communicate's timeout to achieve this kind of things). In your use case (issue #12157), I think that letting the test block is fine, since: - there's no easy way to add a timeout (but you could spawn a new interpreter and use communicate with a timeout if you really wanted to) - it will be caught by the faulthandler module - a test killed by faulthandler's timeout is more interesting to fix that a "common" failed test ;-) |
|||
| msg139099 - (view) | Author: mouad (mouad) * | Date: 2011年06月25日 16:37 | |
Thanks for the instructive feedback :) I totally agree i guess there is a lot of issues that i didn't think of :-(, my first thinking was to use "Pool.join" timeout argument but it was removed in 3.2 (by the way i didn't find the issue or the rational that lead to this change). And now that i know about "faulthandler" module i guess that will make also my life easier :), i will rewrite the patch in the issue #12157 to not use any *fancy* way to check if it will hang. cheers, |
|||
| msg139123 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2011年06月25日 22:09 | |
alarm() is one possible implementation, but Charles-François listed some drawbacks. You can also use resource.setrlimit(RLIMIT_CPU), but the timeout is the CPU time (e.g. you cannot stop a sleep) and it is not portable (e.g. resource is not available on Windows). Another possible implementation is a thread. faulthandler uses an "hidden" thread (implemented in C): a thread ignoring all signals using pthread_sigmask. Python threads are not reliable for a timeout because of the GIL, and it is not easy to "interrupt" another thread from the "timeout" thread. For example, you cannot (easily) raise an exception in another thread. > I'm not sure there's a reliable way to write such a general-purpose > wrapper I agree, but it doesn't mean that it is not possible :-) I think that you should try to implement in C a thread ignoring all signals. It becomes more complex when you have to implement the "interrupt the current thread" (current thread, or maybe the thread using the operation_timeout context manager?) part. I suppose that you will have to use low-level "tricks" and you will have to experiment your tool on different platform. You should start this project outside CPython (as a third party module), and then ask for an integration when your work is well tested. You have to know that a module "dies" when it enters CPython: you have to wait something like 18 months to modify it, so you have to be sure that your code is "correct" ;-) |
|||
| msg139127 - (view) | Author: STINNER Victor (vstinner) * (Python committer) | Date: 2011年06月25日 22:46 | |
Oh, there is another possible implementation: use a subprocess. But if the timeout is implemented using a subprocess, the syntax cannot be: with timeout(5): do_something() It should be something like: timeout(5, """if 1: import os, sys ... do_something() ... sys.exit(0) """) Some tests are already doing that manually. |
|||
| msg152692 - (view) | Author: Charles-François Natali (neologix) * (Python committer) | Date: 2012年02月05日 15:31 | |
Closing, since it's hard to write correctly, and apparently not that useful. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:19 | admin | set | github: 56619 |
| 2012年02月05日 15:31:10 | neologix | set | status: open -> closed resolution: rejected messages: + msg152692 stage: resolved |
| 2011年06月25日 22:46:28 | vstinner | set | messages: + msg139127 |
| 2011年06月25日 22:09:31 | vstinner | set | messages: + msg139123 |
| 2011年06月25日 16:37:23 | mouad | set | messages: + msg139099 |
| 2011年06月25日 15:59:03 | neologix | set | nosy:
+ neologix messages: + msg139091 |
| 2011年06月25日 15:39:27 | r.david.murray | set | nosy:
+ vstinner |
| 2011年06月25日 15:00:06 | mouad | set | files: + operation_timeout.patch |
| 2011年06月25日 14:58:26 | mouad | set | files: - operation_timeout.patch |
| 2011年06月25日 14:49:35 | mouad | create | |