[Twisted-Python] signal handlers and threads

Manlio Perillo manlio_perillo at libero.it
Fri May 12 15:30:49 MDT 2006


Scott Lamb ha scritto:
> [...]
>> 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()? 

Yes!
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_raise.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_CRT_signal.asp

Note that it is supported also SIGBREAK (but not documented on msdn).

> Weird! Does it have pthread_kill()? sigprocmask()?
> pthread_sigprocmask()? sigaction()? Do the semantics differ from the
> usual ones?
> 

No, Windows support signals because they are required by ISO C.

I have found this document:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnucmg/html/ucmglp.asp


> Interesting when compared to the Cygwin stuff:
> <http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/sigproc.cc?cvsroot=src>
> 

Pass.

> 
>> 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)
> 

Ok, fine!

> 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."
> 

I have read this and it seems to allow what I'm doing.

> so the self.callFromThread() only matters if the reactor thread is not
> Python's main thread.
> 

There is someone who run the reactor in a child 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. 

But this should not be a problem in Twisted, since there are no blocking
calls.

> (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.
> 

Well, thanks!

Just to add more informations:
when killing a normal Python process with TERM, the Interpreter
terminates without calling the functions registered with atexit.

Now this is strange because the MSDN says that, by default, SIGTERM is
ignored and the Python documentation says that only an handler for
SIGINT is installed.



Regards  Manlio Perillo




More information about the Twisted-Python mailing list