这个思路后来证明不能用于工作。

因为线程调用没有及时返回,所以不能用这种方式来重启服务。

但作为脑洞,也应该作个记录。

import os
import shutil
import datetime
import threading
import time
import inspect
import ctypes
import hashlib

PATH_DIR = "./"

# 求字符串的md5码
def md5_str(org_str):
    md5obj = hashlib.md5()
    md5obj.update(str(org_str).encode("utf8"))
    _hash = md5obj.hexdigest()
    return str(_hash).upper()

# 求一个文件的md5码
def get_file_md5(file_path):
    """
    获取文件md5值
    :param file_path: 文件路径名
    :return: 文件md5值
    """
    with open(file_path, 'rb') as f:
        return md5_str(f.read())

# 求一个文件夹下所有文件MD5码总和的MD5码
def get_path_files(files_path):
    md5_total = ""
    for parent, dirnames, filenames in os.walk(files_path,  followlinks=True):
            for filename in filenames:
                file_path = os.path.join(parent, filename)
                md5_total += get_file_md5(file_path)
    return md5_str(md5_total)

def _async_raise(tid, exctype):
   """raises the exception, performs cleanup if needed"""
   tid = ctypes.c_long(tid)
   if not inspect.isclass(exctype):
      exctype = type(exctype)
   res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
   if res == 0:
      raise ValueError("invalid thread id")
   elif res != 1:
      # """if it returns a number greater than one, you're in trouble,
      # and you should call it again with exc=NULL to revert the effect"""
      ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
      raise SystemError("PyThreadState_SetAsyncExc failed")

# 配合上个_async_raise函数,优雅关闭线程
def stop_thread(thread):
   _async_raise(thread.ident, SystemExit)

# 示例线程
class TestThread(threading.Thread):
   def run(self):
      print("begin")
      time.sleep(0.1)
      print('end')

# 先启动线程,并进行文件夹内所有文件的MD5码求值
t = TestThread()
t.start()
t.join()
files_md5 = get_path_files(PATH_DIR)

while True:
    # 每隔sleep时间,作一次文件夹MD5码求值,如果发生了变化,说明文件更新,则关闭线程,然后重启线程,实现服务的热加载。
    new_files_md5 = get_path_files(PATH_DIR)
    print(new_files_md5)
    if new_files_md5 == files_md5:
        pass
    else:
        files_md5 = new_files_md5
        print("stop thread")
        try:
            stop_thread(t)
        except ValueError as e:
            print(e)
        except SystemError as e:
            print(e)

        finally:
            print("start thread")
            t = TestThread()
            t.start()
            t.join()
    time.sleep(5)

  

===============输出分隔线=============
AD45C4B0E8112D1E238A5E12DBD9735A
AD45C4B0E8112D1E238A5E12DBD9735A
AD45C4B0E8112D1E238A5E12DBD9735A
AD45C4B0E8112D1E238A5E12DBD9735A
AD45C4B0E8112D1E238A5E12DBD9735A
AD45C4B0E8112D1E238A5E12DBD9735A
AD45C4B0E8112D1E238A5E12DBD9735A
AD45C4B0E8112D1E238A5E12DBD9735A
5B63C272EB1642ADA89CA4602584C28C
stop thread
invalid thread id
start thread
begin
end
5B63C272EB1642ADA89CA4602584C28C
5B63C272EB1642ADA89CA4602584C28C
5B63C272EB1642ADA89CA4602584C28C
5B63C272EB1642ADA89CA4602584C28C
D4BB8E11D4936ABF35ABFF638673E753
stop thread
invalid thread id
start thread
begin
end
D4BB8E11D4936ABF35ABFF638673E753
D4BB8E11D4936ABF35ABFF638673E753
27071D9DC57B9D190CBFBAE05FDD76E2
stop thread
invalid thread id
start thread
begin
end
27071D9DC57B9D190CBFBAE05FDD76E2
27071D9DC57B9D190CBFBAE05FDD76E2
27071D9DC57B9D190CBFBAE05FDD76E2
27071D9DC57B9D190CBFBAE05FDD76E2
27071D9DC57B9D190CBFBAE05FDD76E2

最新文章

  1. [数据库事务与锁]详解五: MySQL中的行级锁,表级锁,页级锁
  2. 【JAVA多线程概述】
  3. 利用react来制作评论框
  4. OpenGL矩阵类(C++)
  5. 实践中的Git常用指令分析
  6. Sencha Touch 2.2.1 Custom Icon 自定义图标
  7. 无软驱加载raid驱动安装windows2003及其他微软操作系统
  8. iostat 使用说明
  9. Eclipse中提高Android SDK Manager下载速度方法
  10. mfc---CFileDialog的过滤器
  11. ubuntu下helloworld内核模块编译
  12. JAVA基础-集合(一)
  13. .NET Core:API文档
  14. [Windows Hyper-V-Server]Enable or disable firewall rules under powershell / powershell下启用禁用防火墙规则
  15. PHP 概览
  16. 文件数据缓存(key-Value)
  17. Ubuntu部署可视化爬虫Portia2.0环境以及入门
  18. jQuery Pagination分页插件
  19. 借助IDE到处Runnable JAR 的步骤
  20. HDFS handler

热门文章

  1. Pick of the Week'19 | 图数据库 Nebula 第 47 周看点-- insert 的二三事
  2. reports buileder 触发器的写法
  3. 深入理解JavaScript程序设计
  4. 《Python3 网络爬虫开发实战》学习资料
  5. 剑指Offer-37.二叉树的深度(C++/Java)
  6. java之方法的重载(overload)
  7. CentOS7升级OpenSSL版本
  8. [问题排查]通过调度系统远程执行脚本,报mysql command not found异常
  9. docker redis使用
  10. 网络协议 15 - P2P 协议