ped*_*ram 56 python multithreading wxpython
告诉循环线程停止循环的正确方法是什么?
我有一个相当简单的程序,它在一个单独的threading.Thread
类中ping指定的主机.在这个类中,它会休眠60秒,再次运行直到应用程序退出.
我想在我的实现一个'停止'按钮,wx.Frame
要求循环线程停止.它不需要立即结束线程,它可以在唤醒后停止循环.
这是我的threading
类(注意:我还没有实现循环,但它可能属于PingAssets中的run方法)
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)
Run Code Online (Sandbox Code Playgroud)
在我的wxPyhton框架中,我从"开始"按钮调用此函数:
def CheckAsset(self, asset):
self.count += 1
thread = PingAssets(self.count, asset, self)
self.threads.append(thread)
thread.start()
Run Code Online (Sandbox Code Playgroud)
Jan*_*sky 83
threading.Thread
可以修改函数以允许通过标志停止,而不是子类化.
我们需要一个可运行的函数访问的对象,我们将该标志设置为停止运行.
我们可以使用threading.currentThread()
对象.
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()
Run Code Online (Sandbox Code Playgroud)
诀窍是,正在运行的线程可以附加其他属性.该解决方案建立在假设的基础上
True
False
.运行代码,我们得到以下输出:
$ python stopthread.py
working on task
working on task
working on task
working on task
working on task
Stopping as you wish.
Run Code Online (Sandbox Code Playgroud)
其他替代方法是使用threading.Event
函数参数.默认情况下False
,外部进程可以"设置"(to True
),函数可以使用wait(timeout)
函数了解它.
我们可以wait
零暂停,但我们也可以将它用作休眠计时器(在下面使用).
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()
Run Code Online (Sandbox Code Playgroud)
编辑:我在Python 3.6中尝试过这个.stop_event.wait()
阻止事件(以及while循环)直到释放.它不返回布尔值.stop_event.is_set()
改为使用作品.
如果我们必须立即停止多个线程,因此可以更好地看到药丸杀死的优势,因为一个药丸将适用于所有人.
它doit
根本不会改变,只是main
处理线程有点不同.
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()
Run Code Online (Sandbox Code Playgroud)
Mik*_*oll 25
之前已经在Stack上询问过这个问题.请参阅以下链接:
基本上你只需要设置一个带有stop函数的线程,该函数设置线程将检查的sentinel值.在你的情况下,你将循环中的东西检查sentinel值以查看它是否已更改,如果有,则循环可能会中断并且线程可能会死亡.
ped*_*ram 12
我在Stack上阅读了其他问题,但我仍然对跨类通信感到困惑.这是我接近它的方式:
我使用一个列表来保存__init__
我的wxFrame类的方法中的所有线程:self.threads = []
如何在Python中停止循环线程中的建议?我在我的线程类中使用一个信号,该信号在True
初始化线程类时设置.
class PingAssets(threading.Thread):
def __init__(self, threadNum, asset, window):
threading.Thread.__init__(self)
self.threadNum = threadNum
self.window = window
self.asset = asset
self.signal = True
def run(self):
while self.signal:
do_stuff()
sleep()
Run Code Online (Sandbox Code Playgroud)
我可以通过遍历我的线程来阻止这些线程:
def OnStop(self, e):
for t in self.threads:
t.signal = False
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
233297 次 |
最近记录: |