การหยุด python โดยใช้ ctrl + c


128

ฉันมีสคริปต์ python ที่ใช้เธรดและส่งคำขอ HTTP จำนวนมาก ฉันคิดว่าสิ่งที่เกิดขึ้นคือในขณะที่คำขอ HTTP (โดยใช้ urllib2) กำลังอ่านมันถูกบล็อกและไม่ตอบสนองต่อCtrlCการหยุดโปรแกรม มีวิธีแก้ปัญหานี้หรือไม่?


9
ฉันไม่รู้ว่าทำไม แต่อย่างน้อยใน OS X การใช้ Control + Backslash ทำให้มันหยุดทำงานและคุณได้รับกล่องโต้ตอบ "python crash" ... แปลก ไม่ใช่ข้อมูลที่เป็นประโยชน์จริงๆจึงเป็นความคิดเห็น!
micmoo

3
ใช้งานได้จริงกับทุกแอปพลิเคชันใน Terminal ...
micmoo

1
David Beazley ได้อธิบายว่าการขัดจังหวะ Ctrl / C สามารถเปลี่ยนสคริปต์ Python ที่มีเธรด muli ให้เป็นหมู CPU ได้อย่างไร สัมผัสได้ที่นี่ ( stackoverflow.com/questions/990102/… ) พร้อมลิงก์ไปยังการพูดคุยของ Beazley
Ned Deily

คำตอบ:


189

บน Windows, CtrlBreakวิธีเดียวที่แน่ใจคือการใช้ หยุดทุกสคริปต์ python ทันที!

(โปรดทราบว่าในแป้นพิมพ์บางรุ่นจะมีป้ายกำกับ "Break" เป็น "Pause")


4
คืออะไรBreak? ฉันจะพิมพ์ได้อย่างไร?
u0b34a0f6ae

5
ควรมีปุ่ม Pause_Break บนแป้นพิมพ์
jonatron

18
เกิดอะไรขึ้นถ้าไม่มี? ฉันใช้ Intel Macbook และไม่มีแป้นพิมพ์ที่มีคุณสมบัติครบถ้วน
Bluu

53
บน Linux คุณควรใช้ Ctrl-Shift- \
MichałZieliński

12
ctrl + Z ไม่ได้ฆ่าสคริปต์เพียงแค่ซ่อนไว้ที่พื้นหลังและระงับมัน คุณสามารถพิมพ์ fg เพื่อเรียกคืนได้
Shady Xu

84

การกดCtrl+ cในขณะที่โปรแกรม python กำลังทำงานจะทำให้ python เพิ่มKeyboardInterruptข้อยกเว้น เป็นไปได้ว่าโปรแกรมที่สร้างคำขอ HTTP จำนวนมากจะมีรหัสการจัดการข้อยกเว้นจำนวนมาก หากexceptส่วนของtry- exceptบล็อกไม่ได้ระบุข้อยกเว้นที่ควรจับมันจะจับข้อยกเว้นทั้งหมดรวมถึงKeyboardInterruptที่คุณเพิ่งก่อ โปรแกรม python ที่เข้ารหัสอย่างถูกต้องจะใช้ประโยชน์จากไฟล์ลำดับชั้นหลามข้อยกเว้น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

หากคุณไม่สามารถเปลี่ยนรหัสได้ (หรือต้องการฆ่าโปรแกรมเพื่อให้การเปลี่ยนแปลงของคุณมีผล) คุณสามารถลองกดCtrl+ cอย่างรวดเร็ว KeyboardInterruptข้อยกเว้นประการแรกจะทำให้โปรแกรมของคุณหลุดออกจากtryบล็อกและหวังว่าKeyboardInterruptจะมีการยกข้อยกเว้นอย่างใดอย่างหนึ่งในภายหลังเมื่อโปรแกรมอยู่นอกtryบล็อก


1
นี่เป็นคำตอบที่ดีในการเปิดใช้ "ตัวแบ่ง" ที่พบบ่อยที่สุดซึ่งก็คือ ctrl + c
Xerion

53

หากรันใน Python shell ให้ใช้Ctrl+ Zมิฉะนั้นให้ค้นหาpythonกระบวนการและฆ่ามัน


25
^Z-> [1]+ Stopped -> kill %1หยุดงาน # 1 (หรืองาน% 1 ตามที่ bash วางไว้)
u0b34a0f6ae

23
คุ้มค่าที่จะเพิ่มคำตอบว่า Ctrl + Z เพียงแค่หยุดกระบวนการชั่วคราว
Matteo Italia

2
เพื่ออธิบายรายละเอียดด้านบน: การหยุดกระบวนการชั่วคราวจะทำให้กระบวนการนี้อยู่ในหน่วยความจำและในเชลล์ของคุณเพียงแค่ป้องกันไม่ให้ใช้ทรัพยากร CPU ไฟล์ซ็อกเก็ตทุกอย่างยังคงเปิดและใช้งานอยู่ ในความเป็นจริงการพิมพ์fgจะนำมันกลับมา
RandomInsano

2
Ctrl+Zไม่ใช่วิธีที่เหมาะสมในการหยุดสคริปต์ python และควรหลีกเลี่ยงเว้นแต่คุณจะวางแผนที่จะดำเนินการต่อกระบวนการที่หยุดชั่วคราว
Josh Correia

33

กระบวนการขัดจังหวะขึ้นอยู่กับฮาร์ดแวร์และระบบปฏิบัติการ ดังนั้นคุณจะมีพฤติกรรมที่แตกต่างกันมากขึ้นอยู่กับตำแหน่งที่คุณรันสคริปต์ python ตัวอย่างเช่นบนเครื่อง Windows เรามีCtrl+ C( SIGINT) และCtrl+ Break(SIGBREAK )

ดังนั้นในขณะที่ SIGINT มีอยู่ในทุกระบบและสามารถจัดการและจับสัญญาณได้ แต่สัญญาณ SIGBREAK จะเป็นเฉพาะ Windows (และสามารถปิดใช้งานได้ในCONFIG.SYS ) และได้รับการจัดการโดย BIOS เป็นเวกเตอร์ขัดจังหวะINT 1Bhซึ่งเป็นสาเหตุที่ทำให้คีย์นี้ มีพลังมากกว่าที่อื่น ๆ ดังนั้นหากคุณใช้ระบบปฏิบัติการที่มีการปรุงแต่ง * nix คุณจะได้ผลลัพธ์ที่แตกต่างกันขึ้นอยู่กับการใช้งานเนื่องจากสัญญาณนั้นไม่มีอยู่ที่นั่น แต่มีสัญญาณอื่น ๆ ใน Linux คุณสามารถตรวจสอบว่ามีสัญญาณอะไรบ้างโดย:

$ 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

ดังนั้นหากคุณต้องการจับCTRL+BREAK สัญญาณบนระบบ linux คุณจะต้องตรวจสอบว่าสัญญาณ POSIXใดที่พวกเขาแมปคีย์นั้น การแมปยอดนิยม ได้แก่

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

ในความเป็นจริงมีฟังก์ชั่นอื่น ๆ อีกมากมายใน Linux ซึ่งSysRqคีย์ (System Request) สามารถใช้ชีวิตของมันเอง ...


19

โพสต์นี้เก่า แต่เมื่อเร็ว ๆ นี้ฉันพบปัญหาเดียวกันของCtrl+ Cไม่ยุติสคริปต์ Python บน Linux ฉันใช้Ctrl+ \( SIGQUIT)


แม้ว่ามันจะทำให้เกิดการถ่ายโอนข้อมูลหลัก แต่มันก็หยุดสคริปต์ขอบคุณ
ospider

17

Ctrl+Dความแตกต่างสำหรับ Windows และ Linux

ปรากฎว่าใน Python 3.6 ตัวแปล Python จัดการCtrl+ Cต่างกันสำหรับ Linux และ Windows สำหรับ Linux Ctrl+ Cจะทำงานได้ตามที่คาดไว้เป็นส่วนใหญ่อย่างไรก็ตามใน Windows Ctrl+ C ส่วนใหญ่จะไม่ทำงานโดยเฉพาะอย่างยิ่งหาก Python กำลังเรียกใช้การบล็อกการโทรเช่นthread.joinหรือรอการตอบกลับทางเว็บ อย่างไรก็ตามมันใช้งานtime.sleepได้ นี่คือคำอธิบายที่ดีเกี่ยวกับสิ่งที่เกิดขึ้นในล่าม Python สังเกตว่าCtrl+ Cสร้างSIGINTสร้าง

โซลูชันที่ 1: ใช้Ctrl+ Breakหรือเทียบเท่า

ใช้แป้นพิมพ์ลัดด้านล่างในหน้าต่างเทอร์มินัล / คอนโซลซึ่งจะสร้างSIGBREAKที่ระดับต่ำกว่าใน OS และยุติการแปล Python

Mac OS และ Linux

Ctrl+ Shift+ \หรือCtrl+\

Windows :

  • ทั่วไป: Ctrl+Break
  • Dell: Ctrl+ Fn+ F6หรือCtrl+ Fn+S
  • Lenovo: Ctrl+ Fn+ F11หรือCtrl+ Fn+B
  • HP: Ctrl+ Fn+Shift
  • ซัมซุง: Fn+Esc

โซลูชันที่ 2: ใช้ Windows API

ด้านล่างนี้เป็นฟังก์ชันที่มีประโยชน์ซึ่งจะตรวจจับ Windows และติดตั้งตัวจัดการแบบกำหนดเองสำหรับCtrl+ 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)

คุณสามารถใช้ด้านบนดังนี้:

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: วิธีการสำรวจความคิดเห็น

ฉันไม่ชอบหรือแนะนำวิธีนี้เพราะใช้โปรเซสเซอร์และพลังงานโดยไม่จำเป็นส่งผลเสียต่อประสิทธิภาพ

เวลานำเข้าเธรดการนำเข้า

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

ไม่ใน Ubuntu สำหรับทั้ง python 2.7 และ 3.6 การกดctrl + cจะไม่ออก แต่แสดงKeyboardInterruptขึ้น
Rick

7

บน Mac กดCtrl+ \เพื่อออกจากกระบวนการ python ที่เชื่อมต่อกับเทอร์มินัล


3

บน Mac / in Terminal:

  1. แสดงตัวตรวจสอบ (คลิกขวาภายในหน้าต่างเทอร์มินัลหรือเชลล์> แสดงตัวตรวจสอบ)
  2. คลิกไอคอนการตั้งค่าด้านบน "กระบวนการทำงาน"
  3. เลือกจากรายการตัวเลือกภายใต้ "กลุ่มกระบวนการสัญญาณ" (ฆ่ายุติขัดจังหวะ ฯลฯ )

1
  • การบังคับให้ปิดโปรแกรมโดยใช้ Alt + F4 (ปิดโปรแกรมปัจจุบัน)
  • สแปมปุ่ม X บน CMD สำหรับเช่น
  • Taskmanager (Windows + R ตัวแรกและ "taskmgr") จากนั้นจบงาน

สิ่งเหล่านี้อาจช่วยได้


1

คุณสามารถเปิดตัวจัดการงานของคุณ (ctrl + alt + delete จากนั้นไปที่ตัวจัดการงาน) และมองหา python และเซิร์ฟเวอร์ถูกเรียก (เช่นตัวอย่าง) _go_app (หลักการตั้งชื่อคือ: _language_app)

ถ้าฉันจบงาน _go_app มันจะจบเซิร์ฟเวอร์ดังนั้นเมื่อไปที่นั่นในเบราว์เซอร์จะบอกว่า "จบลงโดยไม่คาดคิด" ฉันใช้ git bash ด้วยและเมื่อฉันเริ่มเซิร์ฟเวอร์ฉันไม่สามารถแยกออกจากเซิร์ฟเวอร์ในเชลล์ของ bash ได้ ด้วย ctrl + c หรือ ctrl + pause แต่เมื่อคุณจบงาน python (งานที่ใช้ 63.7 mb) มันจะแยกสคริปต์เซิร์ฟเวอร์ออกเป็น bash และอนุญาตให้ฉันใช้ git bash shell ป้อนคำอธิบายภาพที่นี่


1

สำหรับบันทึกสิ่งที่ฆ่ากระบวนการบนของราสเบอร์รี่ 3B + (วิ่ง raspbian) เป็น+Ctrl 'บนแป้นพิมพ์ AZERTY ภาษาฝรั่งเศสของฉันการสัมผัส'ยังเป็นเลข 4

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.