python:优雅的退出程序或重启服务
来源:互联网 发布:大数据带来的经济效益 编辑:程序博客网 时间:2024/05/16 10:16
使用任务队列有助于松耦合的设计。有时我们不得不重启服务(比如发新版),但不能打断队列中正在进行的任务。
正确的做法是handle sigterm信号,具体代码如下:
import sysimport argparseimport loggingimport signalimport asyncioclass GracefulKiller: kill_now = False def __init__(self): signal.signal(signal.SIGINT, self.exit_gracefully) signal.signal(signal.SIGTERM, self.exit_gracefully) def exit_gracefully(self,signum, frame): self.kill_now = Trueasync def loop_task(): killer = GracefulKiller() while 1: print("ha") # 任务主体 if killer.kill_now: break await asyncio.sleep(2)loop = asyncio.get_event_loop()try: loop.run_until_complete(loop_task())finally: loop.run_until_complete(loop.shutdown_asyncgens()) # see: https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.shutdown_asyncgens loop.close()
异步任务的管理和等待
python3.5 之后,有了比较完善的asyncio库和协程机制。对IO密集型任务,可以使用异步调用在单线程中实现“并发”。极大的增加任务吞吐。
想要让IO 任务并发,只需要使用支持asyncio的库(比如aiohttp),简单的loop.create_task就行。有时,需要限制后台任务的数量,在重启服务的时候,需要等待所有后台并发任务的完成。
此时消费者可以使用信号量进行控制。
import argparseimport loggingimport signalimport asyncioclass GracefulKiller: kill_now = False def __init__(self): signal.signal(signal.SIGINT, self.exit_gracefully) signal.signal(signal.SIGTERM, self.exit_gracefully) def exit_gracefully(self,signum, frame): self.kill_now = Truedef pop_queue(task_queue): try: task_args = task_queue.pop(0) print("dequeue args {}".format(task_args)) except: task_args = None return task_argsasync def wait_tasks_done(semaphore, value): while semaphore._value != value: print("wait all task done!") await asyncio.sleep(1)# 处理单个异步任务async def run_task(task_args, semaphore): print("run_task {}".format(task_args)) await asyncio.sleep(3) # 模拟耗时 print("run_task {} done".format(task_args)) semaphore.release()async def loop_task(): killer = GracefulKiller() loop = asyncio.get_event_loop() task_queue = [x for x in range(0, 10)] # 模拟一个任务队列 task_limit = 2 # 同时允许任务数量 semaphore = asyncio.Semaphore(value=task_limit, loop=loop) while 1: task_args = pop_queue(task_queue) if task_args != None: await semaphore.acquire() loop.create_task(run_task(task_args, semaphore)) if killer.kill_now: await wait_tasks_done(semaphore, task_limit) breakloop = asyncio.get_event_loop()try: loop.run_until_complete(loop_task())finally: loop.run_until_complete(loop.shutdown_asyncgens()) loop.close()
输出:
dequeue args 0dequeue args 1dequeue args 2run_task 0run_task 1run_task 0 donerun_task 1 donewait all task done!run_task 2wait all task done!wait all task done!run_task 2 done
上面的程序,无论何时重启,都将等待所有后台的任务完成。妈妈再也不用担心我被用户投诉然后被祭天了。
阅读全文
0 0
- python:优雅的退出程序或重启服务
- 优雅的“重启”apche服务
- 如何优雅地退出python程序
- boost asio程序优雅的退出 一
- boost asio程序优雅的退出 二
- Android中优雅的退出程序
- 优雅的退出程序---->持续更新
- Android中优雅的退出程序
- nt service 1072 无需重启,重复安装服务程序或服务驱动的方法
- python - 优雅的执行程序
- 优雅的退出应用和处理崩溃异常自动重启
- 微信小程序退出重启
- JVM安全退出(如何优雅的关闭java服务)
- 应用的优雅退出
- Android退出程序三种比较优雅的方式
- 安卓开发如何优雅的实现退出整个程序
- 飘逸的python - 优雅的执行程序
- 如何优雅的退出goroutine
- mysql in() 子查询 优化
- 10. Regular Expression Matching
- JAVA【IO六】序列化
- sublime 关闭tab检测
- (ros/catkin) ××/××.h: No such file or directory
- python:优雅的退出程序或重启服务
- Java基础知识扫盲点
- 字符串排序(冒泡排序法模拟)
- 17.通用的页面跳转逻辑
- JavaWeb学习笔记——获取表单数据
- 航天科工智慧产业
- php笔记2
- NOIP2017游记
- windows安装mongoDB