threading 如何终止线程


import PySimpleGUI as sG
import threading
import time
def gui():
    sG.theme('DarkAmber')

    layout = [
        [sG.InputText('https://www.baidu.com', key='_text_'), sG.FileBrowse('导入', key='_file_'), sG.Button('查询'),
         sG.Button('数据可视'), sG.Cancel('退出')],
        [sG.Table(values=[[]])]
    ]

    window = sG.Window('WebInfoGUI', layout, size=(1200, 700))

    while True:
        event, values = window.read()
        if event in (sG.WIN_CLOSED, None, '退出'):
            print(values)
            break
        window.close()
def job():
    i = 0
    while True:
        i=i+2
        print(i)
        time.sleep(2)

#想要的效果是:关闭gui界面时同时终止线程thread2
#     或者点击退出时终止线程thread2
if __name__ == '__main__':
    thread1 = threading.Thread(target=gui, args=())
    thread2 = threading.Thread(target=job, args=())
    thread1.start()
    thread2.start()



下图是关闭了gui界面,程序仍然运行

img

gui不要用子线程执行,应该放到主线程里执行
子线程的deamon要设置成true,那么当主线程退出时,子线程也自动结束

  • 看下这篇博客,也许你就懂了,链接:使用threading模块创建多线程爬取妹子图网站图集
  • 除此之外, 这篇博客: 如何加速计算?中的 threading 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • Thread 对象数据属性有name(线程名),ident(线程标识符),daemon(线程是否是守护线程)等。主要对象包括start(),run()和join()等。start表示开始执行该线程,run()定义线程功能,通常在子类中被应用开发者重写,join (timeout=None)表示直到启动的线程终止之前一直挂起,除非给出timeout秒,否则会一直阻塞。

    import threading
    import time
    def read():
        for x in range(5):
            print('在%s,正在听音乐' % time.ctime())
            time.sleep(1.5)
    def write():
        for x in range(5):
            print('在%s,正在看电视' % time.ctime())
            time.sleep(1.5)
    
    def main():
        music_threads = []  # 用来存放执行read函数线程的列表
        TV_threads = []  # 用来存放执行write函数线程的列表
        for i in range(1,2):  # 创建1个线程用于read(),并添加到read_threads列表
            t = threading.Thread(target=read) # 执行的函数如果需要传递参数,threading.Thread(target=函数名,args=(参数,逗号隔开))
            music_threads.append(t)
        for i in range(1,2): # 创建1个线程执行write(),并添加到write_threads列表
            t = threading.Thread(target=write) # 执行的函数如果需要传递参数,threading.Thread(target=函数名,args=(参数,逗号隔开))
            TV_threads.append(t)
        for i in range(0,1):  # 启动存放在read_threads和write_threads列表中的线程
            music_threads[i].start()
            TV_threads[i].start()
    if __name__ == '__main__':
        main()
    

    本例参考博客

    为了让线程更好的封装,可以用threading模块下的Thread类,继承这个类,然后实现run方法,线程就回自动运行run方法中的代码。

    import threading
    import time
    count = 0
    class MyThread(threading.Thread):
        def __init__(self , threadName):
            super(MyThread,self).__init__(name=threadName)
        """一旦这个MyThread类被调用,自动的就会运行底下的run方法中的代码,
        因为这个run方法所属的的MyThread类继承了threading.Thread"""
        def run(self):
            global count
            for i in range(100):
                count += 1
                time.sleep(0.3)
                print(self.getName() , count)
    for i in range(2):
        MyThread("MyThreadName:" + str(i)).start()
    
  • 以下回答由chatgpt基于相关博客总结生成:

    在Python中,可以通过以下方式来终止线程:

    1. 引入标准库threading来管理线程,使用threading.Event()来控制线程的启动和终止。具体来说,可以在线程中定期调用该Event实例的wait()方法以检查是否收到终止线程的信号,如果收到则退出线程。

    示例代码:

    import threading
    import time
    
    def task(event):
        while not event.is_set():
            # 线程执行的任务
            print("Thread is running...")
            time.sleep(1)
        print("Thread is stopped.")
    
    # 创建Event实例
    stop_event = threading.Event()
    
    # 创建并启动线程
    thread = threading.Thread(target=task, args=(stop_event,))
    thread.start()
    
    # 在需要结束线程的时候设置Event,线程会在下一次wait()方法调用时检测到该Event并退出循环
    stop_event.set()
    
    # 等待线程结束
    thread.join()
    
    1. 在GUI界面中,可以添加退出按钮,在按钮的回调函数中对线程进行终止。具体来说,可以使用flag来控制线程的启停,当flag为False时线程退出循环。

    示例代码:

    import threading
    import time
    import tkinter as tk
    
    def task(flag):
        while flag:
            # 线程执行的任务
            print("Thread is running...")
            time.sleep(1)
        print("Thread is stopped.")
    
    # 创建并启动线程
    flag = True
    thread = threading.Thread(target=task, args=(flag,))
    thread.start()
    
    # GUI界面
    def quit_thread():
        global flag
        flag = False
    
    root = tk.Tk()
    btn = tk.Button(root, text="Quit", command=quit_thread)
    btn.pack()
    root.mainloop()
    
    # 等待线程结束
    thread.join()
    

    以上是两种终止Python线程的方式,具体方法可以根据实际情况进行选择。