SIgnal delivery to child threads is blocked in Python 2.x

Pavel Perestoronin eigenein at gmail.com
Fri Mar 1 14:52:59 UTC 2013


Hello,

I think there is an issue caused by the following patch:
http://svnweb.freebsd.org/ports/head/lang/python27/files/patch-Python_thread__pthread.h?view=log

The patch ensures a signal is delivered to the main thread always. This
makes impossible to send a signal to a child process that is spawned by a
child thread. This can be shown on the following script that works
differently in FreeBSD and Linux:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-

    from ctypes import CDLL
    from platform import system
    import threading

    if system() == "FreeBSD":
        libc = CDLL('libc.so')
    else:
        libc = CDLL("libc.so.6")

    sigblock = libc.sigblock

    def test():
        print "sigblock is "
        print sigblock(0)  # Linux shows 0, while FreeBSD shows 2147417855

    if __name__ == "__main__":
        threading.Thread(target=test).start()

There is also the comment to the patch:

> Make sure the singal is delivered to the main thread, where python
runs its signal handlers, not to a random thread that happens to be
executing at the time when signal arrives. This functionality has been
lost since Python 2.3, possible cause is that the linux implementation
of POSIX threads always delivered signal to the main thread. This
bug results in rather annoying inability to terminate threading script
with ^C for example and there could be other issues as well.

But on Linux child threads has no signals blocked and according to Linux
man signal(7):

> If more than one of the threads has the signal unblocked, then the kernel
chooses an arbitrary thread to which to deliver the signal.

Anyway, the patch makes Python scripts that use threading work differently
in FreeBSD and Linux.

--
Pavel Perestoronin

E-mail: eigenein at gmail.com
Web: www.eigenein.info


More information about the freebsd-ports-bugs mailing list