python停止线程,如何在Python中停止循环线程?

What's the proper way to tell a looping thread to stop looping?

I have a fairly simple program that pings a specified host in a separate threading.Thread class. In this class it sleeps 60 seconds, the runs again until the application quits.

I'd like to implement a 'Stop' button in my wx.Frame to ask the looping thread to stop. It doesn't need to end the thread right away, it can just stop looping once it wakes up.

Here is my threading class (note: I haven't implemented looping yet, but it would likely fall under the run method in PingAssets)

class PingAssets(threading.Thread):

def __init__(self, threadNum, asset, window):

threading.Thread.__init__(self)

self.threadNum = threadNum

self.window = window

self.asset = asset

def run(self):

config = controller.getConfig()

fmt = config['timefmt']

start_time = datetime.now().strftime(fmt)

try:

if onlinecheck.check_status(self.asset):

status = "online"

else:

status = "offline"

except socket.gaierror:

status = "an invalid asset tag."

msg =("{}: {} is {}. \n".format(start_time, self.asset, status))

wx.CallAfter(self.window.Logger, msg)

And in my wxPyhton Frame I have this function called from a Start button:

def CheckAsset(self, asset):

self.count += 1

thread = PingAssets(self.count, asset, self)

self.threads.append(thread)

thread.start()

解决方案

Threaded stoppable function

Instead of subclassing threading.Thread, one can modify the function to allow

stopping by a flag.

We need an object, accessible to running function, to which we set the flag to stop running.

We can use threading.currentThread() object.

import threading

import time

def doit(arg):

t = threading.currentThread()

while getattr(t, "do_run", True):

print ("working on %s" % arg)

time.sleep(1)

print("Stopping as you wish.")

def main():

t = threading.Thread(target=doit, args=("task",))

t.start()

time.sleep(5)

t.do_run = False

t.join()

if __name__ == "__main__":

main()

The trick is, that the running thread can have attached additional properties. The solution builds

on assumptions:

the thread has a property "do_run" with default value True

driving parent process can assign to started thread the property "do_run" to False.

Running the code, we get following output:

$ python stopthread.py

working on task

working on task

working on task

working on task

working on task

Stopping as you wish.

Pill to kill - using Event

Other alternative is to use threading.Event as function argument. It is by

default False, but external process can "set it" (to True) and function can

learn about it using wait(timeout) function.

We can wait with zero timeout, but we can also use it as the sleeping timer (used below).

def doit(stop_event, arg):

while not stop_event.wait(1):

print ("working on %s" % arg)

print("Stopping as you wish.")

def main():

pill2kill = threading.Event()

t = threading.Thread(target=doit, args=(pill2kill, "task"))

t.start()

time.sleep(5)

pill2kill.set()

t.join()

Edit: I tried this in Python 3.6. stop_event.wait() blocks the event (and so the while loop) until release. It does not return a boolean value. Using stop_event.is_set() works instead.

Stopping multiple threads with one pill

Advantage of pill to kill is better seen, if we have to stop multiple threads

at once, as one pill will work for all.

The doit will not change at all, only the main handles the threads a bit differently.

def main():

pill2kill = threading.Event()

tasks = ["task ONE", "task TWO", "task THREE"]

def thread_gen(pill2kill, tasks):

for task in tasks:

t = threading.Thread(target=doit, args=(pill2kill, task))

yield t

threads = list(thread_gen(pill2kill, tasks))

for thread in threads:

thread.start()

time.sleep(5)

pill2kill.set()

for thread in threads:

thread.join()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值