import os
import sys
import time
import logging
import threading
import multiprocessing
class ThreadDaemonTool(object):
"""多线程守护工具"""
def __init__(self, thread_info_list, interval=30, heart_period=5, event=None, logger=None):
if not isinstance(thread_info_list, list):
raise TypeError("invalid thread_info_list")
self._local_vars = threading.local()
self._local_vars.workers = []
self._start = False
self.interval = max(interval, 1)
self.heart_period = max(heart_period, 1)
self.event = event
for thread in thread_info_list:
name = thread.get("name")
target = thread["target"]
args = () if thread.get("args") is None else thread["args"]
kwargs = {} if thread.get("kwargs") is None else thread["kwargs"]
self._local_vars.workers.append(
threading.Thread(name=name, target=target, args=args, kwargs=kwargs)
)
if not self._local_vars.workers:
raise ValueError("thread workers cannot be empty")
self.logger = logging.getLogger(__name__) if not logger else logger
def start(self):
for work in self._local_vars.workers:
try:
work.setDaemon(True)
work.start()
except:
self.logger.exception("thread[{}] start failed!".format(work.getName()))
sys.exit(1)
self._start = True
def run(self):
if not self._start:
self.start()
event = None
if isinstance(self.event, threading.Event):
event = self.event
counter = 0
while True:
if hasattr(event, "is_set") and event.is_set():
self.logger.error("receiving the termination signal, exit immediately.")
os._exit(1)
for work in self._local_vars.workers:
if not work.is_alive():
self.logger.error("thread {} is dead, service exit.".format(work.getName()))
sys.exit(1)
if counter % self.heart_period == 0:
self.logger.info("thread {} is alive.".format(work.getName()))
counter = counter + 1 if counter < 999999999 else 0
time.sleep(self.interval)
class ProcessDaemonTool(object):
"""多进程守护工具"""
def __init__(self, process_info_list, interval=30, heart_period=5, event=None, logger=None):
if not isinstance(process_info_list, list):
raise TypeError("invalid process_info_list")
self._local_vars = threading.local()
self._local_vars.workers = []
self._start = False
self.interval = max(interval, 1)
self.heart_period = max(heart_period, 1)
self.event = event
for process in process_info_list:
name = process.get("name")
target = process["target"]
args = () if process.get("args") is None else process["args"]
kwargs = {} if process.get("kwargs") is None else process["kwargs"]
self._local_vars.workers.append(
multiprocessing.Process(name=name, target=target, args=args, kwargs=kwargs)
)
if not self._local_vars.workers:
raise ValueError("process workers cannot be empty")
self.logger = logging.getLogger(__name__) if not logger else logger
def start(self):
for work in self._local_vars.workers:
try:
work.daemon = True
work.start()
except:
self.logger.exception("process[{}] start failed!".format(work.name))
sys.exit(1)
self._start = True
def run(self):
if not self._start:
self.start()
event = None
if self.event and isinstance(self.event, multiprocessing.synchronize.Event):
event = self.event
counter = 0
while True:
if hasattr(event, "is_set") and event.is_set():
self.logger.error("receiving the termination signal, exit immediately.")
os._exit(1)
for work in self._local_vars.workers:
if not work.is_alive():
self.logger.error("process {} is dead, service exit.".format(work.name))
sys.exit(1)
if counter % self.heart_period == 0:
self.logger.info("process {} is alive.".format(work.name))
counter = counter + 1 if counter < 999999999 else 0
time.sleep(self.interval)
多线程、多进程守护工具
最新推荐文章于 2024-06-01 09:37:51 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)