Skip to content Skip to sidebar Skip to footer

Python: Prevent Signals To Propagate To Child Threads

import threading import time def worker(i): while True: try: print i time.sleep(10) break except Exception, msg:

Solution 1:

As referred in Python's docs, you should use the attribute daemon:

daemon: A boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

The entire Python program exits when no alive non-daemon threads are left.

New in version 2.6.

To control the CTRL+C signal, you should capture it changing the handler with the signal.signal(signal_number, handler) function. The child process inherits the signal handler for SIGINT.

import threading
import time
import signal


defworker(i):
    whileTrue:
        try:
            print(i)
            time.sleep(10)
            breakexcept Exception as msg:
            print(msg)


defsignal_handler(signal, frame):
    print('You pressed Ctrl+C!')
    print("I will wait for all threads... waiting to be finished")
    for t in threads:
        t.join()

signal.signal(signal.SIGINT, signal_handler)

threads = []
for i inrange(10):
    t1 = threading.Thread(target=worker, args=(i,))
    threads.append(t1)

for t in threads:
    t.start()

print("started all threads... waiting to be finished")
for t in threads:
    t.join()

Solution 2:

if i press ^C while the threads are running, does the thread gets the SIGINT?

No. In Python, only the main thread receives the SIGINT.

Unfortunately, I don't know of a good place in the python source or docs to link to, but you can see that this is true with a simple test:

import threading
import time

defworker():
    whileTrue:
        print('Worker working')
        time.sleep(0.5)
        pass


worker_thread = threading.Thread(target=worker)
worker_thread.start()

whileTrue:
    print('Parent parenting')
    time.sleep(0.5)

After you send SIGINT with ^C, you will see that the main thread is killed (no more 'Parent parenting' logs) and the child thread continues to run.

In your example, your child threads exit because you break out of their while loops after 10 seconds.

Post a Comment for "Python: Prevent Signals To Propagate To Child Threads"