[pygtk] Conflict: raw_input(), SIGALRM and pygtk
Michiel de Hoon
mjldehoon at yahoo.com
Wed Jun 30 09:37:10 WST 2010
The problem is related to how the event loop works. Python (unlike for example Tcl/Tk) does not provide event loop support. Each GUI library (such as PyGTK) therefore implements its own event loop (and is unaware of other event loops). The PyGTK event loop is started automatically when you import gtk. The PyGTK event loop is not aware that you are using the signal module in Python, so it will not call catcher.
You can switch off the PyGTK event loop by calling gtk.set_interactive(False) just after importing gtk. If you do so, you will see that catcher is called again.
However, if you plan to build a PyGTK GUI around your application, then you will have to call gtk.mainloop() at the end of your script, and you will run into the same problem. The solution is then to either convince the Python developers to add event loop support to Python, or to use gtk's machinery to set up alarm signals instead of using Python's signal module:
import gobject
def catcher():
print "beat!"
return True
if __name__ == "__main__":
import gtk
source = gobject.timeout_add(3000, catcher)
raw_input() # to expect "beat!" printing until pressing Enter
gobject.source_remove(source)
Best,
--Michiel
--- On Tue, 6/29/10, Ilya Murav'jov <muravev at yandex.ru> wrote:
> From: Ilya Murav'jov <muravev at yandex.ru>
> Subject: [pygtk] Conflict: raw_input(), SIGALRM and pygtk
> To: pygtk at daa.com.au
> Date: Tuesday, June 29, 2010, 6:01 PM
> Hi all,
>
> I have a console application, using raw_input() (readline)
> for interface
> and SIGALRM for periodic work. Now I added some GUI with
> PyGTK and all
> was fine until I found out that alarm signals stop to
> arise. The cause
> is, to my regret, just 'import gtk'. Here is the code to
> reproduce:
>
> import signal
> import readline # turn on readline
>
> def catcher(signum, _ignored_):
> print "beat!"
>
> if __name__ == "__main__":
> import gtk # <- causes alarm signals not
> to be delivered
>
> signal.signal(signal.SIGALRM, catcher)
> signal.setitimer(signal.ITIMER_REAL, 3, 3)
>
> raw_input() # to expect "beat!" printing
> until pressing Enter
>
> On the one hand, I need raw_input() to use all goodies that
> readline
> has; on the other hand, using (classic, Unix) signals is
> the only way to
> bypass the blocking of raw_input(). I tried to find the
> reason of
> signals-pygtk conflict for 2 days, but no much results; any
> help is
> appreciate. I am using Ubuntu Karmic, Python 2.6.
>
> As I see from Python sources, blocking behaviour of
> raw_input() is done
> via custom select(), see Modules/readline.c,
> readline_until_enter_or_signal(); and when signal SIGALRM
> is arisen,
> select() is interrupted with errno == EINTR which causes my
> function
> catcher() to be invoked (via PyErr_CheckSignals()). But
> when I 'import
> gtk', EINTR stops to arise, how can it happen?
>
> Thanks in advance,
> Ilya Murav'jov
> _______________________________________________
> pygtk mailing list pygtk at daa.com.au
> http://www.daa.com.au/mailman/listinfo/pygtk
> Read the PyGTK FAQ: http://faq.pygtk.org/
>
More information about the pygtk
mailing list