多线程、多进程守护工具

该代码段展示了如何使用Python实现多线程和多进程的守护工具。类ThreadDaemonTool和ProcessDaemonTool分别用于管理线程和进程,确保它们在运行过程中能够被正确启动和监控。工具支持设置守护线程/进程、检查心跳、接收到终止信号时优雅退出等功能,适用于后台服务的稳定运行。
摘要由CSDN通过智能技术生成
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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值