multiprocessing 让子进程忽略信号,手动关闭子进程
起因
同事想要写一个代码,主进程中监听SIGINT、SIGTERM信号退出,并关闭启动的子进程,代码类似这样
import signal
import sys
import time
from multiprocessing import Process
from multiprocessing import Manager
class Test:
def __init__(self):
self.is_running = True
if sys.platform != 'win32':
signal.signal(signal.SIGHUP, self._signal_handler)
signal.signal(signal.SIGINT, self._signal_handler)
signal.signal(signal.SIGTERM, self._signal_handler)
def _signal_handler(self, signum, frame):
"""
Terminate scenario ticking when receiving a signal interrupt
"""
self.is_running = False
print('关闭场景调度')
def listen_manage(self, running, kill_task_lst):
"""监控取消任务"""
while running.value:
kill_task_lst.append(1)
time.sleep(1)
print("child is running")
def run(self):
"""启动场景调度"""
kill_task_lst = Manager().list()
running = Manager().Value(bool, True)
print('启动监控进程')
p = Process(target=self.listen_manage, args=(running, kill_task_lst, ))
p.start()
while self.is_running:
time.sleep(0.5)
print("main is running")
但是发现在ctrl + c 时候,子进程也同时接收到了信号,退出了
启动监控进程
main is running
main is running
child is running
main is running
关闭场景调度
Process Process-3:
Traceback (most recent call last):
File "D:\software\anaconda\envs\test_egg1\lib\multiprocessing\process.py", line 315, in _bootstrap
self.run()
File "D:\software\anaconda\envs\test_egg1\lib\multiprocessing\process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "D:\python_projects\pythonProject\test_egg\test.py", line 35, in listen_manage
time.sleep(1)
KeyboardInterrupt
main is running
这时猜想到可能是子进程也监听了SIGINT,退出了程序,所以想在子任务中设置忽略信号,改造后的 listen_manage:
def listen_manage(self, running, kill_task_lst):
"""监控取消任务"""
if sys.platform != 'win32':
signal.signal(signal.SIGHUP, signal.SIG_IGN)
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGTERM, signal.SIG_IGN)
while running.value::
kill_task_lst.append(1)
time.sleep(1)
print("child is running")
运行后会报 BrokenPipeError: [WinError 232] 管道正在被关闭。
启动监控进程
main is running
main is running
child is running
main is running
关闭场景调度
main is running
child is running
Process Process-4:
Traceback (most recent call last):
File "D:\software\anaconda\envs\test_egg1\lib\multiprocessing\process.py", line 315, in _bootstrap
self.run()
File "D:\software\anaconda\envs\test_egg1\lib\multiprocessing\process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "D:\python_projects\pythonProject\test_egg\test.py", line 37, in listen_manage
kill_task_lst.append(1)
File "<string>", line 2, in append
File "D:\software\anaconda\envs\test_egg1\lib\multiprocessing\managers.py", line 834, in _callmethod
conn.send((self._id, methodname, args, kwds))
File "D:\software\anaconda\envs\test_egg1\lib\multiprocessing\connection.py", line 206, in send
self._send_bytes(_ForkingPickler.dumps(obj))
File "D:\software\anaconda\envs\test_egg1\lib\multiprocessing\connection.py", line 280, in _send_bytes
ov, err = _winapi.WriteFile(self._handle, buf, overlapped=True)
BrokenPipeError: [WinError 232] 管道正在被关闭。
这里想到的原因是父进程直接退出了,导致共享变量kill_task_lst被关闭导致的,所以想在关闭管道前等待子进程退出
可执行的完整代码:
import signal
import sys
import time
from multiprocessing import Process
from multiprocessing import Manager
class Test:
def __init__(self):
self.is_running = True
if sys.platform != 'win32':
signal.signal(signal.SIGHUP, self._signal_handler)
signal.signal(signal.SIGINT, self._signal_handler)
signal.signal(signal.SIGTERM, self._signal_handler)
def _signal_handler(self, signum, frame):
"""
Terminate scenario ticking when receiving a signal interrupt
"""
self.is_running = False
print('关闭场景调度')
def listen_manage(self, running, kill_task_lst):
"""监控取消任务"""
if sys.platform != 'win32':
signal.signal(signal.SIGHUP, signal.SIG_IGN)
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGTERM, signal.SIG_IGN)
while running.value:
kill_task_lst.append(1)
time.sleep(1)
print("child is running")
def run(self):
"""启动场景调度"""
kill_task_lst = Manager().list()
running = Manager().Value(bool, True)
print('启动监控进程')
p = Process(target=self.listen_manage, args=(running, kill_task_lst, ))
p.start()
while self.is_running:
time.sleep(0.5)
print("main is running")
running.set(False)
while p.is_alive():
time.sleep(0.01)
print("finish.....")
if __name__ == '__main__':
t = Test()
t.run()
执行结果:
启动监控进程
main is running
main is running
child is running
main is running
关闭场景调度
main is running
child is running
finish.....
multiprocessing 让子进程忽略信号,手动关闭子进程的更多相关文章
- wait & waitpid 以及子进程传给父进程的信号分析
wait() 和 waitpid() wait() 系统调用挂起调用进程的执行直到有一个孩子终止.调用 wait(&status) 等价于: waitpid(-1, &status, ...
- Linux 父进程发送信号杀死子进程
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <signal. ...
- 第9章 Linux进程和信号超详细分析
9.1 进程简单说明 进程是一个非常复杂的概念,涉及的内容也非常非常多.在这一小节所列出内容,已经是我极度简化后的内容了,应该尽可能都理解下来,我觉得这些理论比如何使用命令来查看状态更重要,而且不明白 ...
- node.js中process进程的概念和child_process子进程模块的使用
进程,你可以把它理解成一个正在运行的程序.node.js中每个应用程序都是进程类的实例对象. node.js中有一个 process 全局对象,通过它我们可以获取,运行该程序的用户,环境变量等信息. ...
- python的multiprocessing模块进程创建、资源回收-Process,Pool
python的multiprocessing有两种创建进程的方式,每种创建方式和进程资源的回收都不太相同,下面分别针对Process,Pool及系统自带的fork三种进程分析. 1.方式一:fork( ...
- 初步理解Python进程的信号通讯
Reference: http://www.jb51.net/article/63787.htm 信号的概念 信号(signal)-- 进程之间通讯的方式,是一种软件中断.一个进程一旦接收到信 ...
- python之multiprocessing创建进程
python的multiprocessing模块是用来创建多进程的,下面对multiprocessing总结一下使用记录. multiprocessing创建多进程在windows和linux系统下的 ...
- Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存
Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存 参考:<linux编程从入门到精通>,<Linux C程序设计大全>,<unix环境高级编程> ...
- Python多进程库multiprocessing创建进程以及进程池Pool类的使用
问题起因最近要将一个文本分割成好几个topic,每个topic设计一个regressor,各regressor是相互独立的,最后汇总所有topic的regressor得到总得预测结果.没错!类似bag ...
随机推荐
- JavaScript有哪些数据类型,它们的区别?
基本数据类型:number.string.boolean.Undefined.NaN(特殊值).BigInt.Symbol 引入数据类型:Object NaN是JS中的特殊值,表示非数字,NaN不是数 ...
- Jmter入门教程
Jmter入门教程 本文已同步到公众号,欢迎关注: 1. 简介 Apache JMeter是一款纯java编写负载功能测试和性能测试开源工具软件.相比Loadrunner而言,JMeter小巧轻便且免 ...
- UiPath存在元素Element Exists的介绍和使用
一.Element Exists的介绍 使您能够验证UI元素是否存在,即使它不可见,输出的是一个布尔值 二.Element Exists在UiPath中的使用 1. 打开设计器,在设计库中新建一个Se ...
- 【机器学习】K-means聚类分析
前言 聚类问题是无监督学习的问题,算法思想就是物以类聚,人以群分,聚类算法感知样本间的相似度,进行类别归纳,对新输入进行输出预测,输出变量取有限个离散值.本次我们使用两种方法对鸢尾花数据进行聚类. 无 ...
- NC19115 选择颜色
NC19115 选择颜色 题目 题目描述 \(n\) 个人排成一个环形,每个人要从 \(c\) 种颜色中选择一个. 牛牛希望相邻的人选择的颜色是不同的 问有多少种方案. 输出方案数对 \(10007\ ...
- Tapdata 肖贝贝:实时数据引擎系列(六)-从 PostgreSQL 实时数据集成看增量数据缓存层的必要性
摘要:对于 PostgreSQL 的实时数据采集, 业界经常遇到了包括:对源库性能/存储影响较大, 采集性能受限, 时间回退重新同步不支持, 数据类型较复杂等等问题.Tapdata 在解决 Pos ...
- PoweJob高级特性-MapReduce完整示例
由于网上搜索 PowerJob MapReduce 都是设计原理,demo也展示个空壳子,没有演示Map到Reduce结果怎么传递,对于没有MR开发经验的人来说并没有什么帮助,所以这里写了一个有完整计 ...
- 5-9 Leaf 分布式ID
Leaf 什么Leaf leaf是叶子的意思 我们使用的Leaf是美团公司开源的一个分布式序列号(id)生成系统 我们可以在Github网站上下载项目直接使用 为什么需要Leaf 上面的图片中 是一个 ...
- 1.9. 触摸按钮(touch pad)测试
1.9.1. 基础 Esp32部分GPIO内置了touch按钮功能(电容式),具体有touch功能的引脚在配置为touchpad后,单片机读入的电容值随是否被触碰发生变化,系统根据电容值的变化判断判断 ...
- CF576A Vasya and Petya's Game
题目大意: 给定一个数字 n,现在 Vasya 要从 1∼n 中想一个数字 x. Petya 向 Vasya 询问 "x 是否能整除 y?" ,通过 Vasya 的回答来判断 x ...