[Twisted-Python] signal handlers and threads
Scott Lamb
slamb at slamb.org
Fri May 12 14:33:46 MDT 2006
On May 12, 2006, at 11:56 AM, Manlio Perillo wrote:
> Hi.
>
> I have written a small module for sending signals to a "foreign"
> Python
> process on Windows 2000/XP.
>
> The trunk is on
> http://svn.berlios.de/svnroot/repos/pykill32/trunk
>
> In this way I can send KILL, TERM and so, like in a POSIX system.
>
> This works by creating a thread on the remote process (yes, Windows
> allow this...) and let it call the function "raise" from the
> MSVCR71 DLL.
Wow, that is sick! I thought _I_ did weird stuff with signals!
So Windows provides signal(), raise(), and the usual signal numbers,
but no kill()? Weird! Does it have pthread_kill()? sigprocmask()?
pthread_sigprocmask()? sigaction()? Do the semantics differ from the
usual ones?
Interesting when compared to the Cygwin stuff: <http://cygwin.com/cgi-
bin/cvsweb.cgi/src/winsup/cygwin/sigproc.cc?cvsroot=src>
> This seems to work fine, and now I can stop a Twisted process with
> kill.py TERM pid
> (does twistd save the pid in a file on Windows?)
>
> but I'm not sure if signal handlers are thread safe.
In Twisted's case, it sure looks to be. See twisted/internet/base.py:
def sigTerm(self, *args):
"""Handle a SIGTERM interrupt.
"""
log.msg("Received SIGTERM, shutting down.")
self.callFromThread(self.stop)
Actually, <http://docs.python.org/lib/module-signal.html> says this:
"Some care must be taken if both signals and threads are used in
the same program. The fundamental thing to remember in using signals
and threads simultaneously is: always perform signal() operations in
the main thread of execution. Any thread can perform an alarm(),
getsignal(), or pause(); only the main thread can set a new signal
handler, and the main thread will be the only one to receive signals
(this is enforced by the Python signal module, even if the underlying
thread implementation supports sending signals to individual
threads). This means that signals can't be used as a means of inter-
thread communication. Use locks instead."
so the self.callFromThread() only matters if the reactor thread is
not Python's main thread.
And Python does seem to provide this guarantee even with your thing.
See signal_handler in <http://svn.python.org/projects/python/trunk/
Modules/signalmodule.c>. It just sets a flag to be picked up later,
and only the main thread does that apparently.
Now, I don't see any guarantee that signals always handled before
entering blocking calls, so they can be delayed forever if nothing
else wakes it up. (This is like their documented note about long
computations but worse.) It does the "normal syscall + flag handler"
stuff I describe at <http://www.slamb.org/projects/sigsafe/api/>.
That's a problem with Python's signal handling everywhere, not with
your thing or Twisted.
Regards,
Scott
--
Scott Lamb <http://www.slamb.org/>
More information about the Twisted-Python
mailing list