473,473 Members | 2,027 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

KeyboardInterrupt vs extension written in C

Hi everyone,

I have tried to do some googling before asking my question here, but I
haven't found any suitable answer. I am developing a Python API for a
graph library written in pure C. The library is doing an awful lot of
math computations, and some of them can take a pretty long time
(depending on the size of the input). If I invoke such calculation from
Python using my own extension, the interpreter locks until the
calculation is complete (I mean, it is not responding to Ctrl-C or
SIGINT).

My question is: is there any way to allow the user to use Ctrl-C to
generate a KeyboardInterrupt and cancel such large computations? I'm
assuming that although pressing Ctrl-C may generate a KeyboardInterrupt
in Python, it is not propagated to the user level until the call into
the graph library returns. I tried to add Py_BEGIN_ALLOW_THREADS before
the call to the underlying C library and Py_END_ALLOW_THREADS after
returning from it, but I had no luck.

Thanks in advance for your answers,
--
Tamas <nt****@gmail.com>

Oct 20 '05 #1
4 3393
Tamas Nepusz wrote:
Hi everyone,

I have tried to do some googling before asking my question here, but I
haven't found any suitable answer. I am developing a Python API for a
graph library written in pure C. The library is doing an awful lot of
math computations, and some of them can take a pretty long time
(depending on the size of the input). If I invoke such calculation from
Python using my own extension, the interpreter locks until the
calculation is complete (I mean, it is not responding to Ctrl-C or
SIGINT).

My question is: is there any way to allow the user to use Ctrl-C to
generate a KeyboardInterrupt and cancel such large computations? I'm
assuming that although pressing Ctrl-C may generate a KeyboardInterrupt
in Python, it is not propagated to the user level until the call into
the graph library returns. I tried to add Py_BEGIN_ALLOW_THREADS before
the call to the underlying C library and Py_END_ALLOW_THREADS after
returning from it, but I had no luck.


I'm not especially an expert with C-extensions. So I'm not sure if I can
be of any help here. But if what you really are after is "only"
terminating the whole program (instead of just the computation, and then
continue), you might consider threads. Do the calls in a separate
thread, and make that a daemon-thread. Then things _should_ work as
expected, as the main thread will receive the signal. Hopefully... if
your call releases the GIL. Which Py_*_ALLOW_THREADS seems to do. So -
give it a try :)

Diez
Oct 20 '05 #2
No, that's actually a bit more complicated. The library I'm working on
is designed for performing calculations on large-scale graphs (~10000
nodes and edges). I want to create a Python interface for that library,
so what I want to accomplish is that I could just type "from igraph
import *" in a Python command line and then access all of the
functionalities of the igraph library. Now it works, except the fact
that if, for example, I start computing the diameter of a random graph
of ~100000 nodes and ~200000 edges, I can't cancel it, because the
KeyboardInterrupt is not propagated to the Python toplevel (or it isn't
even generated until the igraph library routine returns). I would like
to allow the user to cancel the computation with the usual Ctrl-C and
return to the Python interactive interface.
This whole feature is not vital, but it would mean a big step towards
user-friendliness.
I have access to the source code of igraph as well (since one of my
colleagues is developing it), so another possible solution would be to
inject some calls into the igraph source code which temporarily cancels
the computation and checks whether there's something waiting in the
Python interpreter, but I haven't found any function in the API which
allows me to do this.

Tamas

Oct 20 '05 #3
Quoth "Tamas Nepusz" <nt****@gmail.com>:
| No, that's actually a bit more complicated. The library I'm working on
| is designed for performing calculations on large-scale graphs (~10000
| nodes and edges). I want to create a Python interface for that library,
| so what I want to accomplish is that I could just type "from igraph
| import *" in a Python command line and then access all of the
| functionalities of the igraph library. Now it works, except the fact
| that if, for example, I start computing the diameter of a random graph
| of ~100000 nodes and ~200000 edges, I can't cancel it, because the
| KeyboardInterrupt is not propagated to the Python toplevel (or it isn't
| even generated until the igraph library routine returns). I would like
| to allow the user to cancel the computation with the usual Ctrl-C and
| return to the Python interactive interface.
| This whole feature is not vital, but it would mean a big step towards
| user-friendliness.
| I have access to the source code of igraph as well (since one of my
| colleagues is developing it), so another possible solution would be to
| inject some calls into the igraph source code which temporarily cancels
| the computation and checks whether there's something waiting in the
| Python interpreter, but I haven't found any function in the API which
| allows me to do this.

Hm, tough question. Even in C, this would be a little awkward.
If you only wanted the program to abort on ^C, then you could just
replace the default sigint handler with SIG_DFL. But then you'd be
back to the shell prompt, not the python prompt. If you want to
catch the signal, but also abort a computation, then as you say,
the computation needs to check periodically.

Rather than peek into Python for this, I'm wondering if your module
could set its own signal handler for SIGINT, which would set a library
flag. Then call PyErr_SetInterrupt(), to emulate the normal signal
handler.

Donn Cave, do**@drizzle.com
Oct 21 '05 #4
"Tamas Nepusz" <nt****@gmail.com> writes on 20 Oct 2005 15:39:54 -0700:
The library I'm working on
is designed for performing calculations on large-scale graphs (~10000
nodes and edges). I want to create a Python interface for that library,
so what I want to accomplish is that I could just type "from igraph
import *" in a Python command line and then access all of the
functionalities of the igraph library. Now it works, except the fact
that if, for example, I start computing the diameter of a random graph
of ~100000 nodes and ~200000 edges, I can't cancel it, because the
KeyboardInterrupt is not propagated to the Python toplevel (or it isn't
even generated until the igraph library routine returns).


Python installs a "SIGINT" handler that just notes that
such a signal was received. The note is handled during
bytecode execution. This way, Python handles the (dangerous)
asynchronous signal synchronously (which is much safer).
But, it also means that a signal during execution of your C extension
is only handled when it finished.

What you can do in your wrapper code:

Temporarily install a new handler for "SIGINT" that
uses "longjmp" to quit the C extension execution when
the signal occurs.

Note that "longjmp" is dangerous. Great care is necessary.

It is likely that SIGINT occurrences will lead to big
resource leaks (because your C extension will have no
way to release resources when it gets quit with "longjmp").
Dieter
Oct 22 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Ivan Nestlerode | last post by:
Hello comp.lang.python, I am attempting to write a threaded program right now in Python (version 2.3 on Debian unstable) and the current behavior of KeyboardInterrupt is causing me grief. From...
0
by: PantherSE | last post by:
Hello, Ok, here's my situation. I have a small application that listens to messages on a UDP port. When I pass None to settimeout(), and I hit Ctrl+C to interrupt the wait my exception...
4
by: Tony Nelson | last post by:
I'm trying to find out what is eating some KeyboardInterrupt exceptions in a fairly large program (yum). My KeyboardInterrupt handler is called for some Ctl-C presses, but for others nothing seems...
0
by: Fredrik Tolf | last post by:
Dear List, I was writing a Python extension module, including a sleeping call to poll(2), and noticed, to my great surprise (and joy), that even when blocking there, KeyboardInterrupt still...
1
by: Petr Prikryl | last post by:
Do you think that the following could became PEP (pre PEP). Please, read it, comment it, reformulate it,... Abstract Introduction of the mechanism for language extensions via modules...
6
by: ruka_at_ | last post by:
Hi, why is KeyboardInterrupt not caught (xp)? import sys try: inp = sys.stdin.read() except (KeyboardInterrupt, SystemExit): print "kbd-interr,SystemExit" except EOFError: print "eof...
2
by: Michael Goerz | last post by:
Hi, when I try to catch ctrl+c with except KeyboardInterrupt: pychecker tells me Catching a non-Exception object (KeyboardInterrupt)
1
by: radim.marek | last post by:
Hi Guys, during testing of my project on FreeBSD I've discovered stange 'feature' of time.sleep(). It works if single thread is running, but when multi-threaded, the SIGINT signal seems not to...
7
by: Brendon Costa | last post by:
Hi all, I have a small python project i am working on. Basically i always have two threads. A "Read" thread that sits in a loop reading a line at a time from some input (Usually stdin) and then...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.