Menghentikan python menggunakan ctrl + c

128

Saya memiliki skrip python yang menggunakan utas dan membuat banyak permintaan HTTP. Saya pikir apa yang terjadi adalah bahwa sementara permintaan HTTP (menggunakan urllib2) sedang membaca, itu memblokir dan tidak merespons CtrlCuntuk menghentikan program. Apakah ada cara untuk mengatasi ini?

jonatron
sumber
9
Saya tidak tahu mengapa, tetapi setidaknya pada OS X, menggunakan Control + Backslash menyebabkannya berhenti dan Anda mendapatkan dialog "python crashed" ... aneh. Bukan info yang benar-benar berguna, jadi itu adalah komentar!
micmoo
3
Sebenarnya itu bekerja pada semua aplikasi di Terminal ...
micmoo
1
David Beazley telah menjelaskan bagaimana interupsi Ctrl / C dapat mengubah skrip Python muli-berulir menjadi babi CPU. Tersentuh di sini ( stackoverflow.com/questions/990102/… ) dengan tautan ke pembicaraan Beazley.
Ned Deily

Jawaban:

189

Di Windows, satu-satunya cara pasti adalah menggunakan CtrlBreak. Hentikan setiap skrip python secara instan!

(Perhatikan bahwa pada beberapa keyboard, "Break" diberi label sebagai "Jeda".)

Denis Masyukov
sumber
4
Apa Break? Bagaimana cara saya mengetiknya?
u0b34a0f6ae
5
Seharusnya ada tombol Pause_Break di keyboard Anda
jonatron
18
Bagaimana jika tidak ada? Saya menggunakan Intel Macbook, dan tidak memiliki keyboard dengan fitur lengkap.
Bluu
53
Di Linux Anda harus menggunakan Ctrl-Shift- \
Michał Zieliński
12
ctrl + Z tidak mematikan skrip, hanya menyembunyikannya ke latar belakang dan menangguhkannya. Anda dapat mengetik fg untuk mengingatnya.
Shady Xu
84

Menekan Ctrl+ cketika program python sedang berjalan akan menyebabkan python memunculkan KeyboardInterrupteksepsi. Kemungkinan program yang membuat banyak permintaan HTTP akan memiliki banyak kode penanganan perkecualian. Jika exceptbagian dari try- exceptblok tidak menentukan pengecualian mana yang harus ditangkap, itu akan menangkap semua pengecualian termasuk KeyboardInterruptyang baru saja Anda sebabkan. Program python yang dikodekan dengan benar akan menggunakan hierarki pengecualian python dan hanya menangkap pengecualian yang diturunkan Exception.

#This is the wrong way to do things
try:
  #Some stuff might raise an IO exception
except:
  #Code that ignores errors

#This is the right way to do things
try:
  #Some stuff might raise an IO exception
except Exception:
  #This won't catch KeyboardInterrupt

Jika Anda tidak dapat mengubah kode (atau harus mematikan program sehingga perubahan Anda akan berlaku) maka Anda dapat mencoba menekan Ctrl+ cdengan cepat. Yang pertama dari KeyboardInterruptpengecualian akan mengetuk program anda keluar dari tryblok dan mudah-mudahan salah satu kemudian KeyboardInterruptpengecualian akan dibangkitkan ketika program luar dari tryblok.

David Locke
sumber
1
Ini adalah jawaban yang bagus untuk mengaktifkan "break" yang paling umum yaitu ctrl + c.
Xerion
53

Jika itu berjalan di shell Python menggunakan Ctrl+ Z, jika tidak menemukan pythonproses dan membunuhnya.

Andrew Hare
sumber
25
^Z-> [1]+ Stopped -> kill %1untuk menghentikan pekerjaan # 1 (atau pekerjaan% 1 seperti yang dikatakan bash)
u0b34a0f6ae
23
Layak ditambahkan ke jawaban bahwa Ctrl + Z hanya menjeda proses.
Matteo Italia
2
Untuk menguraikan hal di atas: Menjeda proses menyimpannya di dalam memori dan di shell Anda, itu hanya mencegahnya dari menggunakan sumber daya CPU. File, soket, semuanya masih terbuka dan sedang digunakan. Bahkan, mengetik fgakan mengembalikannya.
RandomInsano
2
Ctrl+Zbukan cara yang tepat untuk menghentikan skrip python dan harus dihindari kecuali Anda berencana melanjutkan proses yang dijeda.
Josh Correia
33

Proses interupsi tergantung pada perangkat keras dan OS. Jadi Anda akan memiliki perilaku yang sangat berbeda tergantung di mana Anda menjalankan skrip python Anda. Misalnya, pada mesin Windows kami memiliki Ctrl+ C( SIGINT) dan Ctrl+ Break( SIGBREAK).

Jadi, sementara SIGINT hadir pada semua sistem dan dapat ditangani dan ditangkap, sinyal SIGBREAK khusus untuk Windows (dan dapat dinonaktifkan di CONFIG.SYS ) dan benar-benar ditangani oleh BIOS sebagai vektor interupsi INT 1Bh , itulah sebabnya kunci ini jauh lebih kuat daripada yang lain. Jadi jika Anda menggunakan beberapa OS beraroma * nix, Anda akan mendapatkan hasil yang berbeda tergantung pada implementasinya, karena sinyal itu tidak ada di sana, tetapi yang lain juga. Di Linux Anda dapat memeriksa sinyal apa yang tersedia untuk Anda dengan:

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGEMT       8) SIGFPE       9) SIGKILL     10) SIGBUS
11) SIGSEGV     12) SIGSYS      13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGURG      17) SIGSTOP     18) SIGTSTP     19) SIGCONT     20) SIGCHLD
21) SIGTTIN     22) SIGTTOU     23) SIGIO       24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGPWR      30) SIGUSR1
31) SIGUSR2     32) SIGRTMAX

Jadi jika Anda ingin menangkap CTRL+BREAK sinyal pada sistem linux, Anda harus memeriksa sinyal POSIX apa yang telah dipetakan kunci tersebut. Pemetaan populer adalah:

CTRL+\     = SIGQUIT 
CTRL+D     = SIGQUIT
CTRL+C     = SIGINT
CTRL+Z     = SIGTSTOP 
CTRL+BREAK = SIGKILL or SIGTERM or SIGSTOP

Bahkan, banyak fungsi lagi yang tersedia di Linux, di mana SysRq(System Request) kunci dapat mengambil kehidupan sendiri ...

not2qubit
sumber
19

Posting ini sudah tua tetapi saya baru-baru ini mengalami masalah yang sama yaitu Ctrl+ Ctidak menghentikan skrip Python di Linux. Saya menggunakan Ctrl+ \( SIGQUIT).

Junius L.
sumber
Meskipun itu akan menyebabkan dump inti, tetapi skrip itu berhenti, terima kasih
ospider
17

Ctrl+ DPerbedaan untuk Windows dan Linux

Ternyata pada Python 3.6, juru bahasa Python menangani Ctrl+ Cberbeda untuk Linux dan Windows. Untuk Linux, Ctrl+ Cakan berfungsi sebagian besar seperti yang diharapkan, namun pada Windows Ctrl+ C sebagian besar tidak berfungsi terutama jika Python menjalankan panggilan pemblokiran seperti thread.joinatau menunggu respons web. Namun itu berhasil time.sleep. Inilah penjelasan yang bagus tentang apa yang terjadi pada interpreter Python. Perhatikan bahwa Ctrl+ Cmenghasilkan SIGINT.

Solusi 1: Gunakan Ctrl+ Breakatau Setara

Gunakan pintasan keyboard di bawah ini di jendela terminal / konsol yang akan menghasilkan SIGBREAKpada level yang lebih rendah di OS dan menghentikan interpreter Python.

Mac OS dan Linux

Ctrl+ Shift+ \atau Ctrl+\

Windows :

  • Umum: Ctrl+Break
  • Dell: Ctrl+ Fn+ F6atau Ctrl+ Fn+S
  • Lenovo: Ctrl+ Fn+ F11atau Ctrl+ Fn+B
  • HP: Ctrl+ Fn+Shift
  • Samsung: Fn+Esc

Solusi 2: Gunakan Windows API

Di bawah ini adalah fungsi praktis yang akan mendeteksi Windows dan menginstal custom handler untuk Ctrl+ Cdi konsol:

#win_ctrl_c.py

import sys

def handler(a,b=None):
    sys.exit(1)
def install_handler():
    if sys.platform == "win32":
        import win32api
        win32api.SetConsoleCtrlHandler(handler, True)

Anda dapat menggunakan di atas seperti ini:

import threading
import time
import win_ctrl_c

# do something that will block
def work():
    time.sleep(10000)        
t = threading.Thread(target=work)
t.daemon = True
t.start()

#install handler
install_handler()

# now block
t.join()

#Ctrl+C works now!

Solusi 3: Metode polling

Saya tidak suka atau merekomendasikan metode ini karena itu tidak perlu mengkonsumsi prosesor dan daya berdampak negatif pada kinerja.

impor threading waktu impor

def work():
    time.sleep(10000)        
t = threading.Thread(target=work)
t.daemon = True
t.start()
while(True):
    t.join(0.1) #100ms ~ typical human response
# you will get KeyboardIntrupt exception
Shital Shah
sumber
Tidak, di Ubuntu, untuk python 2.7 dan 3.6, menekan ctrl + ctidak berhenti tetapi menunjukkan KeyboardInterrupt.
Rick
7

Pada Mac, tekan Ctrl+ \untuk keluar dari proses python yang terpasang pada terminal.

Krunal
sumber
3

Di mac / di Terminal:

  1. Tampilkan Inspektur (klik kanan dalam jendela terminal atau Shell> Show Inspector)
  2. klik ikon Pengaturan di atas "proses yang sedang berjalan"
  3. pilih dari daftar opsi di bawah "Kelompok Proses Sinyal" (Bunuh, hentikan, interupsi, dll).
AG452
sumber
1
  • Memaksa program ditutup menggunakan Alt + F4 (mematikan program saat ini)
  • Spamming tombol X pada CMD untuk ex
  • Taskmanager (Windows + R pertama dan kemudian "taskmgr") dan kemudian mengakhiri tugas.

Itu mungkin membantu.

Sisi gelap dari Gaming
sumber
1

Anda dapat membuka task manager Anda (ctrl + alt + delete, kemudian pergi ke task manager) dan melihatnya melalui python dan server dipanggil (sebagai contoh) _go_app (konvensi penamaan adalah: _language_app).

Jika saya mengakhiri tugas _go_app itu akan mengakhiri server, jadi pergi ke sana di browser akan mengatakan itu "tiba-tiba berakhir", saya juga menggunakan git bash, dan ketika saya memulai server, saya tidak bisa keluar dari server di shell bash dengan ctrl + c atau ctrl + pause, tetapi setelah Anda mengakhiri tugas python (yang menggunakan 63,7 mb) itu akan keluar dari skrip server di bash, dan izinkan saya untuk menggunakan shell git bash. masukkan deskripsi gambar di sini

JORDANO
sumber
1

Sebagai catatan, apa yang membunuh proses pada Raspberry 3B + saya (menjalankan raspbian) adalah Ctrl+ '. Pada keyboard AZERTY Prancis saya, sentuhannya 'juga nomor 4.

Bertinchamps
sumber