gpt4 book ai didi

python - 杀死 Python 中的所有线程

转载 作者:行者123 更新时间:2023-11-28 17:42:09 24 4
gpt4 key购买 nike

我有一个 python 脚本,它会持续 ping 一些 IP 并将结果打印到屏幕上。但我想通过按键(最好使用 q 键或通过 ctrl c)终止脚本,然后终止所有线程。

实现此目标的最佳方法是什么?我的代码如下...

import os
import re
import time
import sys
import subprocess
import Queue
import threading

def screen_output(x, y, text):
sys.stdout.write("\x1b7\x1b[%d;%df%s\x1b8" % (x, y, text))
sys.stdout.flush()

class pingo:

def __init__(self,hosts):
self.q = Queue.Queue()
self.all_results = {}
self.hosts = hosts

def send_ping(self,q,ip):
self.q.put(self.record_results(ip))

def record_results(self,ip):
ping_count = 0

host_results = {
"device" : None,
"sent_count" : 0,
"success_count": 0,
"fail_count": 0,
"failed_perc": 0,
"curr_status": None
}


while True:
rc = subprocess.call(['ping', '-c', '1', '-W', '1', ip], stdout=open('/dev/null', 'w'), stderr=open('/dev/null', 'w'))
ping_count += 1

# update stats

sent_count = host_results['sent_count']
success_count = host_results['success_count']
fail_count = host_results['fail_count']
failed_perc = host_results['failed_perc']
curr_status = host_results['curr_status']

sent_count += 1

if rc == 0:
success_count += 1
curr_status = "Successful Response"
else:
fail_count += 1
curr_status = "Request Timed Out"

failed_perc = ( fail_count / sent_count ) * 100

host_results.update({'failed_perc': failed_perc, 'fail_count': fail_count, 'success_count': success_count, 'curr_status': curr_status, 'sent_count': sent_count})
time.sleep(0.5)
self.all_results.update({ip:host_results})
screen_output(0,0,self.all_results)
return True

def go(self):
for i in self.hosts:
t = threading.Thread(target=self.send_ping, args = (self.q,i))
#t.daemon = True
t.start()

p = pingo(["8.8.8.8"])
p.go()

编辑:我尝试按照建议添加全局 ALIVE 标志,但这仍然无法通过 CRTL-C 终止线程。

import sys
import subprocess
import Queue
import threading
import signal

def screen_output(x, y, text):
sys.stdout.write("\x1b7\x1b[%d;%df%s\x1b8" % (x, y, text))
sys.stdout.flush()

class pingo:

def __init__(self,hosts):
self.q = Queue.Queue()
self.all_results = {}
self.hosts = hosts
self.ALIVE = True

def signal_handler(self,signal, frame):
self.ALIVE = False

def send_ping(self,q,ip):
self.q.put(self.record_results(ip))

def record_results(self,ip):
ping_count = 0

host_results = {
"device" : None,
"sent_count" : 0,
"success_count": 0,
"fail_count": 0,
"failed_perc": 0,
"curr_status": None
}


while self.ALIVE:
try:
rc = subprocess.call(['ping', '-c', '1', '-W', '1', ip], stdout=open('/dev/null', 'w'), stderr=open('/dev/null', 'w'))
ping_count += 1

# update stats

sent_count = host_results['sent_count']
success_count = host_results['success_count']
fail_count = host_results['fail_count']
failed_perc = host_results['failed_perc']
curr_status = host_results['curr_status']

sent_count += 1

if rc == 0:
success_count += 1
curr_status = "Successful Response"
else:
fail_count += 1
curr_status = "Request Timed Out"

failed_perc = ( fail_count / sent_count ) * 100

host_results.update({'failed_perc': failed_perc, 'fail_count': fail_count, 'success_count': success_count, 'curr_status': curr_status, 'sent_count': sent_count})
time.sleep(0.5)
self.all_results.update({ip:host_results})
screen_output(0,0,self.all_results)
except KeyboardInterrupt:
signal.signal(signal.SIGINT, self.signal_handler)
return True


def go(self):
for i in self.hosts:
t = threading.Thread(target=self.send_ping, args = (self.q,i))
#t.daemon = True
t.start()

p = pingo(["8.8.8.8"])
p.go()

最佳答案

设置一个全局标志 ALIVE(或者不一定是全局的,你可以使用字典或类属性),绑定(bind)到 SIGINT 并更改它:

import signal

ALIVE = True

def signal_handler(signal, frame):
global ALIVE
ALIVE = False

signal.signal(signal.SIGINT, signal_handler)

然后只需将循环更改为:

def record_results(self,ip):
# some code
while ALIVE:
# some code

这样它会优雅地退出(在收到信号后的某个时间)。

关于python - 杀死 Python 中的所有线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22738717/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com