From: Paul Moore on 6 May 2010 11:59 From a quick experiment, it seems that select.select with a timeout doesn't react to a keyboard interrupt until the timeout expires. Specifically, if I do s = socket.socket() select.select([s], [], [], 30) and then press Ctrl-C, Python waits for the 30 seconds before raising KeyboardInterrupt. Is this a known limitation on Windows? I see no mention of it in the documentation. Assuming it is a known limitation, is there a way round it? (I'm writing a tiny server using asyncore/asynchat, and the delayed response to Ctrl-C is a mild nuisance. Solutions such as "use twisted", while probably the sensible option in a wider context, don't really apply here - I need something within the confines of the stdlib if it's to be worth doing). Thanks, Paul
From: Thomas Heller on 6 May 2010 15:58 Paul Moore schrieb: >>From a quick experiment, it seems that select.select with a timeout > doesn't react to a keyboard interrupt until the timeout expires. > Specifically, if I do > > s = socket.socket() > select.select([s], [], [], 30) > > and then press Ctrl-C, Python waits for the 30 seconds before raising > KeyboardInterrupt. > > Is this a known limitation on Windows? I see no mention of it in the > documentation. Assuming it is a known limitation, is there a way round > it? (I'm writing a tiny server using asyncore/asynchat, and the > delayed response to Ctrl-C is a mild nuisance. Solutions such as "use > twisted", while probably the sensible option in a wider context, don't > really apply here - I need something within the confines of the stdlib > if it's to be worth doing). If you look at the source code for time.sleep(), which CAN be interrupted by pressing Ctrl-C, you will find that it is carefully programmed to be interruptible (sp?). Which is not the case for select.select(), obviously. I guess the best way might be to split your select.select() call into several ones, using a smaller timeout like 1 second for example. BTW: I have experimented with calling the win32 function SetConsoleCtrlHandler() before the call to select.select(). This allows to install a python callback function which is called when Ctrl+C is pressed. However it seems this callback is not able to interrupt the select() call - but it can 'raise SystemExit()' which will terminate the script. Here is the code: """ import ctypes, select, socket @ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_uint) def HandlerRoutine(dwCtrlType): print "hoppla", dwCtrlType if dwCtrlType == 0: # CTRL+C raise SystemExit() return 1 s = socket.socket() print "Waiting." ctypes.windll.kernel32.SetConsoleCtrlHandler(HandlerRoutine, 1) select.select([s], [], [], 30) ctypes.windll.kernel32.SetConsoleCtrlHandler(HandlerRoutine, 0) print "Done." """
From: Paul Moore on 7 May 2010 04:48 On 6 May, 20:58, Thomas Heller <thel...(a)ctypes.org> wrote: > If you look at the source code for time.sleep(), which CAN be interrupted > by pressing Ctrl-C, you will find that it is carefully programmed to be > interruptible (sp?). Which is not the case for select.select(), obviously. Thanks - given this, would it be worth me submitting a documentation patch noting that select.select is not interruptible on Windows? > I guess the best way might be to split your select.select() call into several > ones, using a smaller timeout like 1 second for example. Yes, that's probably good enough for my case. > BTW: I have experimented with calling the win32 function SetConsoleCtrlHandler() > before the call to select.select(). This allows to install a python callback > function which is called when Ctrl+C is pressed. However it seems this callback > is not able to interrupt the select() call - but it can 'raise SystemExit()' > which will terminate the script. Here is the code: That's useful - I doubt I'll need it for this case, but I'll keep it in mind for the future. Thanks for the help. Paul.
From: Giampaolo Rodolà on 7 May 2010 10:36 You can easily avoid this by setting a lower timeout when calling asyncore.loop(), like 1 second or less (for example, Twisted uses 0.001 secs). Actually there's no reason for asyncore to have such a high default timeout (30 seconds). I think this should be signaled on the bug tracker. --- Giampaolo http://code.google.com/p/pyftpdlib http://code.google.com/p/psutil 2010/5/6 Paul Moore <p.f.moore(a)gmail.com>: > >From a quick experiment, it seems that select.select with a timeout > doesn't react to a keyboard interrupt until the timeout expires. > Specifically, if I do > > s = socket.socket() > select.select([s], [], [], 30) > > and then press Ctrl-C, Python waits for the 30 seconds before raising > KeyboardInterrupt. > > Is this a known limitation on Windows? I see no mention of it in the > documentation. Assuming it is a known limitation, is there a way round > it? (I'm writing a tiny server using asyncore/asynchat, and the > delayed response to Ctrl-C is a mild nuisance. Solutions such as "use > twisted", while probably the sensible option in a wider context, don't > really apply here - I need something within the confines of the stdlib > if it's to be worth doing). > > Thanks, > Paul > -- > http://mail.python.org/mailman/listinfo/python-list >
From: Antoine Pitrou on 7 May 2010 14:37 Le Fri, 07 May 2010 16:36:44 +0200, Giampaolo Rodolà a écrit : > You can easily avoid this by setting a lower timeout when calling > asyncore.loop(), like 1 second or less (for example, Twisted uses 0.001 > secs). > Actually there's no reason for asyncore to have such a high default > timeout (30 seconds). The reason for a high default timeout would be to avoid waking the CPU and do useless work too often. This is important on laptops and smaller devices, in order to conserve power. Under Unix, it's easy to have a separate fd on which you write a byte when an signal comes, and which wakes up your select() call. Under Windows, it may be more involved -- first because select() only takes sockets, not pipes.
|
Next
|
Last
Pages: 1 2 3 4 Prev: crash in Py_EnterRecursiveCall Next: List comprehension + lambdas - strange behaviour |