Python,停止线程 [英] Python, Stop a Thread
问题描述
我正在尝试创建一个可ping通IP地址并记录连接时间/未连接时间的类.
I'm trying to create a class that pings an ip address and keeps a record for connected/ not connected times.
由于此类是GUI的一部分,因此我希望在用户询问时停止该线程.
Since this class is a part of a GUI, I wish to stop this thread when asked by user.
发现了一些解决该问题的问答,但实际上没有一个导致线程停止.
Found some Q&As regrading this issue, but neither one actually causes thread to stop.
我正在尝试制作一个方法,该类的一部分将停止self.run()
I'm trying to make a method, a part of this class that will stop self.run()
这是我的Pinger
课:
class Pinger(threading.Thread):
def __init__(self, address='', rate=1):
threading.Thread.__init__(self)
self.address = address
self.ping_rate = rate
self.ping_vector, self.last_ping = [], -1
self.start_time, self.last_status = datetime.datetime.now(), []
self.timestamp, self.time_vector = 0, [datetime.timedelta(0)] * 4
def run(self):
self.start_ping()
def start_ping(self):
self.timestamp = datetime.datetime.now()
while True:
ping_result = os.system('ping %s -n 1 >Null' % self.address)
self.ping_vector.append(ping_result)
if self.last_ping != ping_result:
text = ['Reachable', 'Lost']
print(str(self.timestamp)[:-4], self.address, text[ping_result])
round_time_qouta = datetime.datetime.now() - self.timestamp
self.timestamp = datetime.datetime.now()
self.update_time_counter(ping_result, round_time_qouta)
self.last_ping = ping_result
time.sleep(self.ping_rate)
def update_time_counter(self, ping_result=0, time_quota=datetime.timedelta(0)):
"""self.time_vector = [[cons.succ ping time],[cons.not_succ ping time],
[max accum succ ping time],[max accum not_succ ping time] """
p_vec = [0, 1]
self.time_vector[p_vec[ping_result]] += time_quota
if self.time_vector[p_vec[ping_result]].total_seconds() > self.time_vector[
p_vec[ping_result] + 2].total_seconds():
self.time_vector[p_vec[ping_result] + 2] = self.time_vector[p_vec[ping_result]]
self.time_vector[p_vec[ping_result - 1]] = datetime.timedelta(0)
self.last_status = [ping_result, self.chop_milisecond(self.time_vector[ping_result]),
self.chop_milisecond(self.time_vector[ping_result + 2]),
self.chop_milisecond(datetime.datetime.now() - self.start_time)]
print(str(self.timestamp)[:-4], "State: " + ['Received', 'Lost'][ping_result],
" Duration: " + self.last_status[1], " Max Duration: " + self.last_status[2],
"Total time: " + self.last_status[3])
def chop_milisecond(self, time):
return str(time).split('.')[0]
推荐答案
As I was saying in my comment, the easiest way is to use threading.Event
to signal your thread when it should exit. That way you can expose the event and let other threads set it while you can check for its state from within your thread and exit on request.
在您的情况下,它可能很简单:
In your case, it could be as simple as:
class Pinger(threading.Thread):
def __init__(self, address='', rate=1):
threading.Thread.__init__(self)
self.kill = threading.Event()
# the rest of your setup...
# etc.
def start_ping(self):
self.timestamp = datetime.datetime.now()
while not self.kill.is_set():
# do your pinging stuff
# etc.
然后,每当您希望线程停止运行时(例如从您的UI),只需对其调用:pinger_instance.kill.set()
就可以了.请记住,由于os.system()
的阻塞和Pinger.start_ping()
方法末尾的time.sleep()
,它可能需要一些时间才能被杀死.
Then whenever you want the thread stopped (like from your UI), just call on it: pinger_instance.kill.set()
and you're done. Keep in mind, tho, that it will take some time for it to get killed due to the blocking os.system()
call and due to the time.sleep()
you have at the end of your Pinger.start_ping()
method.
这篇关于Python,停止线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!