İş 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ı?
İş 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ı?
Yanıtlar:
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.)
Break? Nasıl yazacağım?
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 .
Python kabuğunda çalışıyorsa Ctrl+ kullanın Z, aksi takdirde pythonişlemi bulun ve öldürün.
^Z-> [1]+ Stopped -> kill %11. işi (veya
fgonu hemen geri getirecektir.
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.
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 ...
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 :
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
ctrl + cçıkmıyor ama gösteriliyor KeyboardInterrupt.
Bunlar yardımcı olabilir.
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. 
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.