Python 函数长时间运行不退出,线程池任务死锁等问题
import threadpool import threading import time class FuncTTLMonitorDecorator(object): class _ResultThread(threading.Thread): def __init__(self, target, *args, **kwargs): super().__init__(daemon=True) self.func = target self.args = args self.kwargs = kwargs self.result = None def run(self): self.result = self.func(*self.args, **self.kwargs) def get_result(self): try: return self.result except Exception as e: return None def __init__(self, ttl, result_parse_func=None): self.ttl = int(ttl) self.result_parse_func = result_parse_func def run(self, func, *args, **kwargs) -> dict: """ :param func: :param args: :param kwargs: :return: 参数原样返回 """ result = { 'has_ttl': True, 'ttl': self.ttl, 'success': False, 'error': f'The function {func.__name__}(...) timeout({self.ttl} seconds)', 'args': args, 'kwargs': kwargs, 'data': None } _t = self._ResultThread(func, *args, **kwargs) for i in range(self.ttl): time.sleep(1) if not _t.get_result(): continue result.update(success=True, error='', data=_t.get_result()) break if self.result_parse_func: return self.result_parse_func(result) return result def __call__(self, func): def wrapper(*args, **kwargs): return self.run(func, *args, **kwargs) return wrapper def general_login(args_dict, times=1): device = args_dict.get('device') try: while True: time.sleep(1) except Exception as e: device.update(error=str(e), success=False) return device def ttl_result_parse(result): if not result.get('has_ttl'): return result if result.get('success'): data = result.get('data') else: data = result.get('args')[0].get('device') data.update(success=False, error=result.get('error')) return data if __name__ == '__main__': pool = threadpool.ThreadPool(2) args_list = [ {'device': {'ip': '10.100.235.9', 'brand': 'Aruba', 'model': '7210', 'device_type': 'aruba_os'}, 'commands': ['show running-config'] }, { 'device': {'ip': '10.100.235.10', 'brand': 'Aruba', 'model': '7210', 'device_type': 'aruba_os'}, 'commands': ['show running-config'] }, { 'device': {'ip': '10.100.235.1', 'brand': 'Aruba', 'model': '7210', 'device_type': 'aruba_os'}, 'commands': ['show running-config'] } ] results = [] tasks = threadpool.makeRequests( callable_=FuncTTLMonitorDecorator(ttl=3, result_parse_func=ttl_result_parse)(general_login), args_list=args_list, callback=lambda req, res: results.append(res) ) [pool.putRequest(task) for task in tasks] pool.wait() import json print(json.dumps(results, indent=4))
output: [ { "ip": "10.100.235.9", "brand": "Aruba", "model": "7210", "device_type": "aruba_os", "success": false, "error": "The function general_login(...) timeout(3 seconds)" }, { "ip": "10.100.235.10", "brand": "Aruba", "model": "7210", "device_type": "aruba_os", "success": false, "error": "The function general_login(...) timeout(3 seconds)" }, { "ip": "10.100.235.1", "brand": "Aruba", "model": "7210", "device_type": "aruba_os", "success": false, "error": "The function general_login(...) timeout(3 seconds)" } ]