python如何让后台线程执行必要的操作后再退出?

我写了一个web服务,服务启动的时候会另起一个线程去扫描特定目录的文件入库,并且把文件名及扫描的位置记入redis。

  • 文件大小会变动(其他程序尾部写入)

  • 文件数目也会变动

  • 我不知道什么时候变动

所以这个扫描的线程是每分钟去遍历一次文件目录。现在问题来了:

  1. 如果扫描线程是Daemon线程,那么Web服务一关,它立马随之结束,可能已扫描信息还没有记录,重启Web服务的时候数据会不同步。

  2. 如果扫描线程是非Daemon线程,即便Web服务关闭的时候手动关闭扫描线程,由于time.sleep(60)语句会阻塞线程,线程不会立即结束,也很麻烦。

我现在采用的是方法1,在主程序关闭的时候手动关闭扫描线程,并且sleep了1s,防止子线程直接退出。感觉非常粗糙……

求问优雅的实现方式。

阅读 10.3k
2 个回答

需要的是线程间通信的方式,当主线程结束时,发一个信号给扫描线程,然后join它。扫描线程收到后,结束自己。
线程间通信的方式有很多了,比如用Thread Event。甚至你用redis来通信都没问题

例子

import threading
import time

class StoppableThread(threading.Thread):
    def __init__(self, event):
        super(StoppableThread, self).__init__()
        self.event = event

    def run(self):
        while True:
            print('OK')
            if self.event.wait(timeout=1): # 这里的timeout可以是1分钟
                break # 表示有人通知要退出了

event = threading.Event()
t = StoppableThread(event)
t.start()
time.sleep(5)
event.set()
t.join()

用 Condition 替代 sleep

import threading  
import time

cond= threading.Condition() # 条件锁
isStoped=False

def thd(cond):
    print('开始')
    n=0
    while 1:
        cond.acquire() # 锁
        n+=1
        print(n) # 要完成的事      
        cond.wait(1) # 休眠 1秒 , 改为60秒 就是1分钟了
        if isStoped:break # 退出线程循环 
        cond.release() # 解锁
        
    cond.release() # 解锁
    print('结束')
    
#启动线程
threading.Thread(target=thd,args=(cond,)).start()
time.sleep(10) # 等10秒,让线程干事

cond.acquire()
isStoped=True # 设置结束标志
cond.notify() # 唤醒休眠的线程,立即结束。
cond.release()
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏