GNU/Linux >> Belajar Linux >  >> Linux

Tidak dapat mematikan skrip Python dengan Ctrl-C

Saya pikir yang terbaik adalah memanggil join() di utas Anda saat Anda mengharapkannya mati. Saya telah memberanikan diri untuk mengubah loop Anda menjadi akhir (Anda juga dapat menambahkan kebutuhan pembersihan apa pun yang diperlukan di sana). Variabel die diperiksa pada setiap pass dan saat True , program keluar.

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 dan sinyal hanya terlihat oleh proses (yaitu utas utama)... Lihat Ctrl-c yaitu KeyboardInterrupt untuk mematikan utas di python


Ctrl +C mengakhiri utas utama, tetapi karena utas Anda tidak dalam mode daemon, utas tetap berjalan, dan itu membuat proses tetap hidup. Kita bisa menjadikannya daemon:

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

Tapi kemudian ada masalah lain - setelah utas utama memulai utas Anda, tidak ada lagi yang bisa dilakukan. Jadi itu keluar, dan utasnya langsung hancur. Jadi, mari jaga utas utama tetap hidup:

import time
while True:
    time.sleep(1)

Sekarang akan tetap mencetak 'pertama' dan 'kedua' sampai Anda menekan Ctrl +C .

Edit: seperti yang ditunjukkan oleh komentator, utas daemon mungkin tidak mendapat kesempatan untuk membersihkan hal-hal seperti file sementara. Jika Anda membutuhkannya, tangkap KeyboardInterrupt pada utas utama dan minta koordinasi pembersihan dan penutupan. Namun dalam banyak kasus, membiarkan utas daemon mati tiba-tiba mungkin cukup baik.


Versi perbaikan dari jawaban @Thomas K:

  • Mendefinisikan fungsi asisten is_any_thread_alive() menurut inti ini, yang dapat mengakhiri main() otomatis.

Contoh kode:

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. Tidak dapat mengkompilasi Python.h – Kesalahan instalasi Websockify

  2. Ubah direktori kerja di shell dengan skrip python

  3. Jalankan skrip Python melalui crontab

  1. Aljabar Vektor di Scientific Linux 7.1 dengan Python Script:Bagian 1

  2. Menjalankan Script Dengan “. ” Dan Dengan “sumber”?

  3. Cara menghentikan secara manual skrip Python yang berjalan terus menerus di linux

  1. Jalankan Script Dengan Argumen Sebagai Pengguna?

  2. Cara Dockerize Aplikasi Python Dengan Miniconda

  3. nama dasar dengan spasi dalam skrip bash?