Python 通过定时器,停止无线循环的线程

有一个线程,它执行的是一个无线循环的任务
当这个线程长时间没有收到外界的消息的时候,自动停止。
这个时候我们需要一个定时器自动的去计时
比如 超过5秒没有收到消息,则停止。
如果5秒内收到了消息,这个5秒需要被重置,重新计算一个5秒。

import threading
import queue
import time


# 定时器触发时,执行的函数,停止进程
def stop_server(server):
    server.stop()
    print("timer -> stop the server ")

# 实例化定时器
def NewTimer(server):
    timer = threading.Timer(5,stop_server,(server,))
    return timer

# 重置定时器,如果我们输入了内容,则定时器会执行cancel() 和 start(),定时器时间被重置了
def send_msg():
    global  msg_queue
    while True:
        msg = input("请输入要发送的消息\n")
        if msg == "break":
            break
        msg_queue.put(msg)
        print("success send message ->",msg)


# 我们的线程
class Server:
    def __init__(self):
        self._running = True
    
    def stop(self):
        # (这里停止进程,python没有对应的api,我们通过循环,根据判断条件决定是否退出)
        print("server stop")
        self._running = False

    def run(self,name):
        global msg_queue,server,timer
        print(name,"is running ....")

        while self._running: # 循环的判断条件
            try:
                msg = msg_queue.get(timeout=5)
                print("success receive messages ->",msg)
                
                # ------- 接收到消息后,重置定时器 ------------------
                timer.cancel()
                timer = NewTimer(server)  # 取消后定时器就不能用了,必须再次实例化 
                timer.start()
                print("Timer 定时器被重置")

            except  queue.Empty as e:
                print("queue get timeout,请输入break退出")

if __name__ == "__main__":

    # ---------------- 创建一个 发送和接受消息的队列 ------------------
    msg_queue = queue.Queue(5)

    # ---------------- 启动线程-------------------------------------
    server = Server()
    task =  threading.Thread(target=server.run, args=("msg-server",))
    task.start()

    # ---------------- 启动定时器 ---------------------------------
    # timer = threading.Timer(5,stop_server,(server,))
    # timer.start()
    timer = NewTimer(server)
    timer.start()

    # ---------------- 向消息队列中发送消息---------------------------------
    send_msg()

    # ---------------- 阻塞 ----------------
    # 其实不用这一步也可以,毕竟我们的listen_timer本身就阻塞住了,主线程不会退出。
    task.join()

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:设计师小姐姐 返回首页