GNU/Linux >> Linux Esercitazione >  >> Linux

Impossibile terminare lo script Python con Ctrl-C

Penso che sia meglio chiamare join() sui tuoi fili quando ti aspetti che muoiano. Mi sono preso la libertà di far terminare la modifica dei tuoi loop (puoi aggiungere anche qualsiasi esigenza di pulizia richiesta). La variabile die viene controllato ad ogni passaggio e quando è True , il programma si chiude.

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 e i segnali sono visti solo dal processo (cioè il thread principale)... Dai un'occhiata a Ctrl-c cioè KeyboardInterrupt per terminare i thread in python


Ctrl +C termina il thread principale, ma poiché i tuoi thread non sono in modalità demone, continuano a funzionare e ciò mantiene vivo il processo. Possiamo renderli demoni:

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

Ma poi c'è un altro problema:una volta che il thread principale ha avviato i tuoi thread, non c'è nient'altro da fare. Quindi esce e i thread vengono distrutti all'istante. Quindi manteniamo vivo il thread principale:

import time
while True:
    time.sleep(1)

Ora continuerà a stampare "primo" e "secondo" finché non premi Ctrl +C .

Modifica: come hanno sottolineato i commentatori, i thread del demone potrebbero non avere la possibilità di ripulire cose come i file temporanei. Se ne hai bisogno, prendi il KeyboardInterrupt sul thread principale e coordinare la pulizia e l'arresto. Ma in molti casi, lasciare che i thread daemon muoiano improvvisamente è probabilmente sufficiente.


Una versione migliorata della risposta di @Thomas K:

  • Definizione di una funzione assistente is_any_thread_alive() secondo questo concetto, che può terminare il main() automaticamente.

Esempi di codici:

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. Algebra vettoriale su Scientific Linux 7.1 con script Python:parte 1

  2. Impossibile compilare Python.h – Errore di installazione di Websockify

  3. Eseguire script con argomenti come utente?

  4. Cambia la directory di lavoro nella shell con uno script python

  5. basename con spazi in uno script bash?

Come scrivere uno script Bash con esempi

Come eseguire un comando Shell con Python

Come eseguire uno script Python in PHP

Come installare Python 2.7 su CentOS 7.1 o 6.7 con Anaconda

Debug in pyCharm con privilegi sudo?

Rendi lo script Python combinato con i pacchetti Linux facilmente installabili per l'utente finale