Ctrl + c kullanarak python'u durdurma


128

İş parçacıkları kullanan ve çok sayıda HTTP isteği yapan bir python betiğim var. Sanırım olan şey, bir HTTP isteği (urllib2 kullanan) okurken, engelliyor ve CtrlCprogramı durdurmak için yanıt vermiyor . Bunun etrafında herhangi bir yol var mı?


9
Nedenini bilmiyorum ama en azından OS X'te Control + Backslash kullanmak onun sonlanmasına ve bir "python çöktü" iletişim kutusu almanıza neden oluyor ... garip. Gerçekten o kadar yararlı bilgi değil, bu yüzden bir yorum!
micmoo

3
Aslında Terminal'deki tüm uygulamalarda çalışıyor ...
micmoo

1
David Beazley, bir Ctrl / C kesmesinin çok iş parçacıklı bir Python betiğini bir CPU domuzuna nasıl dönüştürebileceğini anlattı. Burada ( stackoverflow.com/questions/990102/… ) Beazley'in konuşmasına bir bağlantıyla değinilmiştir .
Ned Deily

Yanıtlar:


189

Windows'ta tek kesin yol kullanmaktır CtrlBreak. Her python betiğini anında durdurur!

(Bazı klavyelerde "Ara" nın "Duraklat" olarak etiketlendiğini unutmayın.)


4
Nedir Break? Nasıl yazacağım?
u0b34a0f6ae

5
Klavyenizde bir Pause_Break düğmesi olmalıdır
jonatron

18
Ya yoksa? Intel Macbook kullanıyorum ve çok özellikli bir klavyesi yok.
Bluu

53
Linux'ta Ctrl-Shift- \
Michał Zieliński

12
ctrl + Z komut dosyasını öldürmez, sadece arka planda gizler ve askıya alır. Geri çağırmak için fg yazabilirsiniz.
Shady Xu

84

Bir python programı çalışırken Ctrl+ tuşuna basmak c, python'un bir KeyboardInterruptistisna oluşturmasına neden olur . Çok sayıda HTTP isteği yapan bir programın çok sayıda istisna işleme kodu olması muhtemeldir. Eğer exceptbir parçasıtry - exceptbloğunun bunun yakalamak hangi istisnalar belirtmez, bu da dahil olmak üzere tüm özel durumları yakalayacak KeyboardInterruptsadece neden olduğunu. Düzgün kodlanmış bir python programı, python istisna hiyerarşisini kullanır ve yalnızca 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

Kodu değiştiremiyorsanız (veya değişikliklerinizin etkili olması için programı sonlandırmanız gerekiyorsa), o zaman Ctrl+ tuşlarına chızlıca basmayı deneyebilirsiniz . KeyboardInterruptİstisnalardan ilki, programınızı trybloktan çıkaracak ve umarım sonraki KeyboardInterruptistisnalardan biri program bir trybloğun dışında olduğunda ortaya çıkacaktır .


1
Bu, ctrl + c olan en yaygın "kesmeyi" etkinleştirmek için harika bir yanıttır.
Xerion

53

Python kabuğunda çalışıyorsa Ctrl+ kullanın Z, aksi takdirde pythonişlemi bulun ve öldürün.


25
^Z-> [1]+ Stopped -> kill %11. işi (veya
bash'ın

23
Ctrl + Z'nin sadece işlemi duraklattığı cevabına eklemeye değer .
Matteo Italia

2
Yukarıdakileri detaylandırmak için: İşlemi duraklatmak, onu bellekte ve kabuğunuzda tutar, sadece CPU kaynaklarını kullanmasını engeller. Dosyalar, soketler, her şey hala açık ve kullanımda. Aslında, yazmak fgonu hemen geri getirecektir.
RandomInsano

2
Ctrl+Zbir python betiğini durdurmanın doğru yolu değildir ve duraklatılan işlemi devam ettirmeyi planlamadığınız sürece bundan kaçınılmalıdır.
Josh Correia

33

Kesme işlemi donanıma ve işletim sistemine bağlıdır. Dolayısıyla, python betiğinizi nerede çalıştırdığınıza bağlı olarak çok farklı davranışlarınız olacaktır. Örneğin, Windows makinelerde Ctrl+ C( SIGINT) ve Ctrl+ Break(SIGBREAK ) var.

Bu nedenle, SIGINT tüm sistemlerde mevcutken ve işlenip yakalanabilirken, SIGBREAK sinyali Windows'a özgüdür (ve CONFIG.SYS'de devre dışı bırakılabilir ) ve gerçekten bir kesme vektörü INT 1Bh olarak BIOS tarafından işlenir , bu yüzden bu anahtar diğerlerinden çok daha güçlüdür. Dolayısıyla, * nix aromalı bir işletim sistemi kullanıyorsanız, uygulamaya bağlı olarak farklı sonuçlar alırsınız, çünkü bu sinyal orada mevcut değil, ancak diğerleri var. Linux'ta hangi sinyallerin size uygun olduğunu şu şekilde kontrol edebilirsiniz:

$ 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

Dolayısıyla , bir linux sistemindeki CTRL+BREAK sinyali yakalamak istiyorsanız, bu anahtarı hangi POSIX sinyalini eşleştirdiklerini kontrol etmeniz gerekir. Popüler eşlemeler şunlardır:

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

Aslında, Linux altında SysRq(Sistem İsteği) anahtarının kendi başına bir yaşam sürebileceği daha birçok işlev mevcuttur ...


19

Bu gönderi eski ama ben son zamanlarda aynı problemle karşılaştım Ctrl+ CLinux'ta Python betiklerini sonlandırmama. Ctrl+ \( SIGQUIT) Kullandım .


Çekirdek
döküme

17

Ctrl+ DWindows ve Linux için Fark

Python 3.6'dan itibaren, Python yorumlayıcısının Ctrl+ CLinux ve Windows için farklı şekilde ele aldığı ortaya çıktı . Linux için, Ctrl+ Cçalışacak çoğunlukla ancak, Windows beklendiği gibi Ctrl+ C çoğunlukla Python gibi çağrı engelleme çalışıyorsa özellikle çalışmıyor thread.joinveya web yanıt bekliyor. time.sleepAncak bunun için çalışıyor . İşte Python yorumlayıcısında olup bitenlerin güzel açıklaması . Ctrl+ CÜrettiğini unutmayın SIGINT.

1.Çözüm: Ctrl+ Breakveya Eşdeğeri Kullanın

SIGBREAKİşletim sisteminde daha düşük düzeyde üretecek ve Python yorumlayıcısını sonlandıracak olan terminal / konsol penceresinde aşağıdaki klavye kısayollarını kullanın .

Mac OS ve Linux

Ctrl+ Shift+ \veya Ctrl+\

Windows :

  • Genel: Ctrl+Break
  • Dell: Ctrl+ Fn+ F6veya Ctrl+ Fn+S
  • Lenovo: Ctrl+ Fn+ F11veya Ctrl+ Fn+B
  • HP: Ctrl+ Fn+Shift
  • Samsung: Fn+Esc

2.Çözüm: Windows API kullanın

Aşağıda Windows'u algılayacak ve konsolda Ctrl+ için özel işleyici kuracak kullanışlı işlevler bulunmaktadır C:

#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)

Yukarıdakileri şu şekilde kullanabilirsiniz:

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!

3. Çözüm: Yoklama yöntemi

İşlemciyi ve gücü gereksiz yere tüketerek performansı olumsuz etkilediği için bu yöntemi tercih etmiyorum veya önermiyorum.

iş parçacığı içe aktarma içe aktarma süresi

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

Hayır, Ubuntu'da hem python 2.7 hem de 3.6 için, tuşuna basmak ctrl + cçıkmıyor ama gösteriliyor KeyboardInterrupt.
Rick

7

Mac'te , terminale bağlı bir python işleminden çıkmak için Ctrl+ tuşuna basın \.


3

Mac / in Terminal'de:

  1. Denetçiyi Göster (terminal penceresi içinde sağ tıklayın veya Kabuk> Denetçiyi Göster)
  2. "çalışan işlemler" in üzerindeki Ayarlar simgesini tıklayın
  3. "Signal Process Group" altındaki seçenekler listesinden seçim yapın (Kill, terminate, interrupt, vb.).

1
  • Alt + F4 kullanarak programı kapanmaya zorlamak (mevcut programı kapatır)
  • Örneğin CMD'de X düğmesini spam yapmak
  • Taskmanager (önce Windows + R ve ardından "taskmgr") ve ardından görevi sonlandırın.

Bunlar yardımcı olabilir.


1

Görev yöneticinizi açabilir (ctrl + alt + delete, sonra görev yöneticisine gidebilir) ve içinde python için bakabilirsiniz ve sunucu (örneğin) _go_app (adlandırma kuralı: _language_app) olarak adlandırılır.

_Go_app görevini bitirirsem, sunucuyu sonlandırır, bu yüzden tarayıcıda oraya gitmek "beklenmedik bir şekilde bitti" diyecektir, ayrıca git bash kullanıyorum ve bir sunucu başlattığımda, bash kabuğundaki sunucudan çıkamıyorum ctrl + c veya ctrl + pause ile, ancak python görevini (63.7 mb kullanan) bitirdiğinizde, bash'da sunucu komut dosyasından çıkacak ve git bash kabuğunu kullanmama izin verecek. görüntü açıklamasını buraya girin


1

Kayıt için, Raspberry 3B + (raspbian çalıştıran) cihazımdaki süreci öldüren şey Ctrl+ idi '. Fransızca AZERTY klavyemde dokunma 'da 4 numara.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.