I have just started learning concurrency in Python, so my concepts may be a bit wrong, in that case please do correct me.
All of the following happened kind of unknowingly.
This is a simple threading example that I understand -
import time
import threading
class CountDown:
def __init__(self):
self._running = True
def stop(self):
self._running = False
def run(self, n):
while self._running is True and n>0:
print(f'T-minus {n}')
n -= 1
time.sleep(2)
c = CountDown()
t = threading.Thread(target=c.run,args=(10,))
t.start()
time.sleep(5)
c.stop()
print('Before join')
t.join()
print('After join')
Which outputs-
T-minus 10
T-minus 9
T-minus 8
Before join
After join
However if I replace the stop
method with terminate
which isn't implemented-
c = CountDown()
t = threading.Thread(target=c.run,args=(10,))
t.start()
time.sleep(5)
c.terminate()
c.stop()
print('Before join')
t.join()
print('After join')
Which outputs-
In [14]: runfile('/home/walker/Desktop/PYTHON/concurrency/2.py', wdir='/home/walker/Desktop/PYTHON/concurrency')
T-minus 10
T-minus 9
T-minus 8
Traceback (most recent call last):
File "<ipython-input-14-3759e536ced7>", line 1, in <module>
runfile('/home/walker/Desktop/PYTHON/concurrency/2.py', wdir='/home/walker/Desktop/PYTHON/concurrency')
File "/home/walker/.local/lib/python3.6/site-packages/spyder_kernels/customize/spydercustomize.py", line 668, in runfile
execfile(filename, namespace)
File "/home/walker/.local/lib/python3.6/site-packages/spyder_kernels/customize/spydercustomize.py", line 108, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "/home/walker/Desktop/PYTHON/concurrency/2.py", line 28, in <module>
c.terminate()
AttributeError: 'CountDown' object has no attribute 'terminate'
In [15]: T-minus 7
T-minus 6
T-minus 5
T-minus 4
T-minus 3
T-minus 2
T-minus 1
NOTE:
Because of c.terminate()
it is clear that Before join
and After join
don't get printed. Which led me to believe that the main thread has crashed.
However as you can see it automatically starts printing again from T-minus 7
which is contrary to what I think, that if the main thread crashes then the child threads would too.
Why is this happening?
Raised Exception crashes only the thread it is in, not the whole program so the process stays alive but If you mark your worker threads as daemon threads, they will die when all your non-daemon threads (e.g. the main thread) have exited.
So if you want to exit the program when your main thread crashes you can set the daemon flag to True
t = threading.Thread(target=c.run,args=(10,), daemon=True)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With