GNU/Linux >> Znalost Linux >  >> Linux

Skript Python nelze zabít pomocí Ctrl-C

Myslím, že je nejlepší zavolat join() na vaše vlákna, když očekáváte, že zemřou. Dovolil jsem si provést změnu tak, aby vaše smyčky skončily (také tam můžete přidat jakékoli potřebné vyčištění). Proměnná die se kontroluje při každém průchodu a když je True , program se ukončí.

import threading
import time

class MyThread (threading.Thread):
    die = False
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name

    def run (self):
        while not self.die:
            time.sleep(1)
            print (self.name)

    def join(self):
        self.die = True
        super().join()

if __name__ == '__main__':
    f = MyThread('first')
    f.start()
    s = MyThread('second')
    s.start()
    try:
        while True:
            time.sleep(2)
    except KeyboardInterrupt:
        f.join()
        s.join()

KeyboardInterrupt a signály vidí pouze proces (tj. hlavní vlákno)... Podívejte se na Ctrl-c, tj. KeyboardInterrupt pro zabíjení vláken v pythonu


Ctrl +C ukončí hlavní vlákno, ale protože vaše vlákna nejsou v režimu démona, běží dál, a to udržuje proces naživu. Můžeme z nich udělat démony:

f = FirstThread()
f.daemon = True
f.start()
s = SecondThread()
s.daemon = True
s.start()

Ale pak je tu další problém - jakmile hlavní vlákno spustí vaše vlákna, nemá nic jiného na práci. Takže to odejde a vlákna jsou okamžitě zničena. Takže udržíme hlavní vlákno naživu:

import time
while True:
    time.sleep(1)

Nyní bude tisknout „první“ a „druhý“, dokud nestisknete Ctrl +C .

Upravit: jak komentátoři poukázali, vlákna démonů nemusí dostat příležitost vyčistit věci, jako jsou dočasné soubory. Pokud to potřebujete, zachyťte KeyboardInterrupt na hlavním vláknu a nechat jej koordinovat vyčištění a vypnutí. Ale v mnoha případech je pravděpodobně dost dobré nechat vlákna démonů náhle zemřít.


Vylepšená verze odpovědi @Thomas K:

  • Definování funkce asistenta is_any_thread_alive() podle této podstaty, která může ukončit main() automaticky.

Příklady kódů:

import threading

def job1():
    ...

def job2():
    ...

def is_any_thread_alive(threads):
    return True in [t.is_alive() for t in threads]

if __name__ == "__main__":
    ...
    t1 = threading.Thread(target=job1,daemon=True)
    t2 = threading.Thread(target=job2,daemon=True)
    t1.start()
    t2.start()

    while is_any_thread_alive([t1,t2]):
        time.sleep(0)

Linux
  1. Jak Dockerize Python aplikací s Miniconda

  2. základní jméno s mezerami ve skriptu bash?

  3. Spusťte skript Python přes crontab

  1. Vektorová algebra na Scientific Linux 7.1 s Python Script:Část 1

  2. ID vlákna Pythonu, jak je uvedeno nahoře

  3. Jak zabít python skript pomocí bash skriptu

  1. Nelze zkompilovat Python.h – Chyba instalace Websockify

  2. Spuštění skriptu s „. “ A se „zdrojem“?

  3. Jak ručně zastavit skript Python, který běží nepřetržitě na linuxu