简体   繁体   中英

Can't stop running thread

I've a python program executing 3 different threads.

t1 = Thread(target=calculate_statistics, args=(ip_slave_1, path_script_slave_1, logger))
t1.daemon = True
t1.start() 
t2 = Thread(target=calculate_statistics, args=(ip_slave_2, path_script_slave_2, logger))
t2.daemon = True
t2.start() 
t3 = Thread(target=computing, args=("1"))
t3.daemon = True
t3.start() 
t1.join()
t2.join()
t3.join()

Thread are executing well. The problem is that to stop the whole program, I have to digit many times CTRL + C. I see this message on the screen: (FIRST CTRL + C) :

^CTraceback (most recent call last):
  File "/mnt/roaming.py", line 116, in <module>
    t1.join()
  File "/usr/lib/python3.9/threading.py", line 1060, in join
  File "/usr/lib/python3.9/threading.py", line 1080, in _wait_for_tstate_lock

c (SECOND CTRL + C)

^CException ignored in: <module 'threading' from '/usr/lib/python3.9/threading.pyc'>
Traceback (most recent call last):
  File "/usr/lib/python3.9/threading.py", line 1477, in _shutdown
KeyboardInterrupt:

Each thread is executing an infinite loop. How can I kill the threads when I press CTRL + C ? This are the threads functions:

def calculate_statistics(ip_slave, path_script_slave, logger):
    while True:
      current_time = datetime.datetime.now()
      result = os.popen("perl " + str(path_script_slave) + "SYSTEMCMD.pl uf_rxinfo all").read()
      rssi = result.split(",",1)[1]
      rssi = rssi.split(",",1)[0]
      agc = result.split(",",1)[1]
      agc = agc.split(",",1)[1]
      agc = agc.split(",",1)[0]
      auth = result.split(",",1)[1]
      auth = auth.split(",",1)[1]
      auth = auth.split(",",1)[0]
      print("[" + str(current_time) + "]"+"[SLAVE]" + "[" + str(ip_slave) + "] " +"RSSI: " + str(rssi) + "; AGC: " + str(agc) + "; AUTH: " + str(auth) +".")
      row = str(current_time) + " -IP " + str(ip_slave) + " -RSSI " + str(rssi) + " -AGC " + str(agc) + " -AUTH " + str(auth)
      logger.info(row)
      time.sleep(0.2)
def computing(f_name):
    time.sleep(1)
    while True:
      a_file = open("slaves.log", "r")
      lines = a_file.readlines()
      last_lines = lines[-8:]
      rssi_slave_1 = []
      rssi_slave_2 = []
      agc_slave_1 = []
      agc_slave_2 = []
      auth_slave_1 = []
      auth_slave_2 = []
      f = open("diff.log", "w")
      for element in last_lines:
        f.write(str(element))
        if(element.split("-IP")[1].split(" ")[1]) == str(ip_slave_1):
          rssi_slave_1.append(element.split("-RSSI")[1].split(" ")[1])
          agc_slave_1.append(element.split("-AGC")[1].split(" ")[1])
          auth_slave_1.append(element.split("-AUTH")[1].split(" ")[1].split("\n")[0])
        else:
          rssi_slave_2.append(element.split("-RSSI")[1].split(" ")[1])
          agc_slave_2.append(element.split("-AGC")[1].split(" ")[1])
          auth_slave_2.append(element.split("-AUTH")[1].split(" ")[1].split("\n")[0])          
      f.close()
      print(rssi_slave_1)
      print(rssi_slave_2)
      print(agc_slave_1)
      print(agc_slave_2)
      print(auth_slave_1)
      print(auth_slave_2)
      algorithm(rssi_slave_1,rssi_slave_2,agc_slave_1,agc_slave_2,auth_slave_1,auth_slave_2)
      time.sleep(1)

The canonical way is to have your main thread wait in an infinite loop, and signal the other threads with a threading.Event and replace any infinite loop within the threads with something that waits for that event to have been set.

stop_event.wait(x) would replace any time.sleep(x) you'd have in the processing loops.

import random
import threading
import time

stop_event = threading.Event()


def ponder(thing):
    while not stop_event.wait(random.uniform(0.9, 1.1)):
        print(f"Thinking about {thing}...")
    print(f"Ah! Stopping thinking about {thing}.")


threads = [
    threading.Thread(target=ponder, args=(arg,))
    for arg in ["spam", "eggs", "toast"]
]

for thread in threads:
    thread.start()

while True:
    try:
        time.sleep(1)
    except KeyboardInterrupt:
        print("Keyboard interrupt caught.")
        stop_event.set()
        break

for thread in threads:
    thread.join()

print("Done!")

The output of this example is eg

Thinking about eggs...
Thinking about spam...
Thinking about toast...
Thinking about eggs...
Thinking about spam...
Thinking about toast...
Thinking about toast...
Thinking about eggs...
Thinking about spam...
Thinking about spam...
Thinking about toast...
Thinking about eggs...
^CKeyboard interrupt caught.
Ah! Stopping thinking about spam.
Ah! Stopping thinking about toast.
Ah! Stopping thinking about eggs.
Done!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM