0

I have a question in Python programming. I am writing a code that has a thread. This thread is a blocked thread. Blocked thread means: a thread is waiting for an event. If the event is not set, this thread must wait until the event is set. My expectation that block thread must wait the event without any timeout for waiting!
After starting the blocked thread, I write a forever loop to calculate a counter. The problem is: When I want to terminate my Python program by Ctrl+C, I can not terminate the blocked thread correctly. This thread is still alive! My code is here.

import threading
import time

def wait_for_event(e):
    while True:
        """Wait for the event to be set before doing anything"""
        e.wait()
        e.clear()
        print "In wait_for_event"

e = threading.Event()
t1 = threading.Thread(name='block',
                      target=wait_for_event,
                      args=(e,))
t1.start()

# Check t1 thread is alive or not
print "Before while True. t1 is alive: %s" % t1.is_alive()

counter = 0
while True:
    try:
        time.sleep(1)
        counter = counter + 1
        print "counter: %d " % counter
    except KeyboardInterrupt:
        print "In KeyboardInterrupt branch"
        break

print "Out of while True"
# Check t1 thread is alive
print "After while True. t1 is alive: %s" % t1.is_alive()

Output:

$ python thread_test1.py
Before while True. t1 is alive: True
counter: 1
counter: 2
counter: 3
^CIn KeyboardInterrupt branch
Out of while True
After while True. t1 is alive: True

Could anyone give me a help? I want to ask 2 questions.
1. Can I stop a blocked thread by Ctrl+C? If I can, please give me a feasible direction.
2. If we stop the Python program by Ctrl+\ keyboard or reset the Hardware (example, PC) that is running the Python program, the blocked thread can be terminated or not?

jackbk
  • 123
  • 1
  • 1
  • 9

2 Answers2

2

Ctrl+C stops only the main thread, Your threads aren't in daemon mode, that's why they keep running, and that's what keeps the process alive. First make your threads to daemon.

t1 = threading.Thread(name='block',
                      target=wait_for_event,
                      args=(e,))
t1.daemon = True
t1.start()

Similarly for your other Threads. But there another problem - once the main thread has started your threads, there's nothing else for it to do. So it exits, and the threads are destroyed instantly. So let's keep the main thread alive:

import time
while True:
    time.sleep(1)

Please have a look at this, I hope you will get your other answers.

Asfandyar Khan
  • 1,677
  • 15
  • 34
  • Could I ask you 2 more questions? I have no experience with thread termination. I will ask 1st question here because it still makes me unclear. In 1st question, I temporarily ignore case "let's keep the main thread alive". If we make t1 thread as `daemon`, is it still alive when we press Ctrl+C? I make t1 thread as `daemon`, but I still see `After while True. t1 is alive: True` when I press Ctrl+C. It means that even the main program can exit, but t1 thread is still running! Is this correct? – jackbk Sep 01 '17 at 04:56
  • Yes its correct... By setting them as daemon threads, you can let them run and forget about them, and when your program quits, any daemon threads are killed automatically. – Asfandyar Khan Sep 06 '17 at 12:29
  • Thank you. I understood about your explanation for daemon thread. My 2nd question is your comment for the main thread: "once the main thread has started your threads, there's nothing else for it to do", "So let's keep the main thread alive". Did You mean that I should not have exception for `KeyboardInterrupt`? I use exception for `KeyboardInterrupt` because my python program must be exited if user presses Ctrl+C. It is my intention. – jackbk Sep 14 '17 at 07:29
1

If you need to kill all running python's processes you can simply run pkill python from the command line. This is a little bit extreme but would work.

An other solution would be to use locking inside your code see here:

Max Alonzo
  • 45
  • 5
  • Thanks. I think we should not kill a program by Ctrl+C or Ctrl+\. It is not a good method to stop a python program. But I am really curious for thread running if we kill python program by Ctrl+C or Ctrl+\. So I asked this problem in this topic. About "locking", I have read it so far but I am not familiar with this method. I am familiar with "event waiting" in SystemC, so I have tried the same method (event waiting) in Python. That is the reason of using blocking thread by "event waiting" in my example. – jackbk Sep 14 '17 at 07:42