Extension libraries, spawned threads, and the global interpreter lock
Damien Elmes
resolve at repose.REMOVE.cx
Thu Jan 3 01:30:02 EST 2002
Thanks for your feedback, Martin.
More below.
martin at v.loewis.de (Martin v. Loewis) writes:
> Damien Elmes <resolve at repose.REMOVE.cx> writes:
>
> > So my question is: am I correct in thinking it's a problem with the GIL not
> > being held in the other threads?
>
> Probably not. Do the other threads ever call back into Python code, or
> invoke Python interpreter API? If so, they need to hold the lock while
> doing so. If they are completely separate, they are not concerned with
> the GIL.
They're entirely seperate, and thus, I thought, safe from the GIL. This problem
appears to crop up when multiple threads receive SIGINT at once.
> > If so, would explicitly grabbing and freeing the lock in the xlib
> > threads solve the problem?
>
> At what time would you free it? As long as one of the threads holds
> the lock, your main thread will not advance.
Thought of that while lying in bed last night :-) Silly of me to mention it in
the first place.
> More likely, you have a problem with signal handlers. Python installs
> a SIGINT handler, to generate the KeyboardInterrupt. This can break
> badly if the signal handler is not delivered to a Python thread, or
> more specifically, to the main Python thread.
>
> You have a number of choices:
>
> - don't install the SIGINT handler, but live with the default SIGINT
> processing (i.e. process termination)
The problem is that the interactive interpreter installs a sigint handler,
which is sort of rude for a library to remove when it's instantianted. I think
the 'default' behavior for interactive use is installed once per statement
anyway, so if I were to try modify the behavior, it wouldn't change this
problem.
> - block SIGINT in the other threads. How to do this much depends on
> your operating system.
Maybe this is worth looking into. So far I've been able to determine:
* when this class calls the backend stuff, two threads are forked, to a total
of three "processes" in a ps listing.
* sending an INT signal to any one of them yields the correct behavior.
* sending an INT signal to the main program thread, and any of the other two
(but only one of the other two) yields the correct behavior
* extmodulethread1 + extmodulethread2 yields the crash.
This problem is compounded by the behaviour of the interactive interpreter - a
C-c seemingly generates an interrupt signal to each of the threads instead of
just the main one.
This problem also doesn't seem to crop up when catching a keyboard error in my
own code, which leads me to believe the erroneous interaction is with exception
stuff - but as I understand it, that's all been thread-safe for a long time.
This behaviour is really perplexing me :-)
--
Damien Elmes
resolve at repose.cx
More information about the Python-list
mailing list