多进程编程
调用terminate
()相当于向进程发送SIGTERM信号
import os,sys import time import signal import multiprocessing def helper(queue,data): def signal_handler(signum, frame): print("son,Killing subprocess") sys.exit() signal.signal(signal.SIGTERM, signal_handler) while True: print("son,I am working,id=%s,data=%s"%(os.getpid(),str(data))) command = queue.get() print('son,my command is',command) time.sleep(2) queue.task_done() def make_pro(): queue = multiprocessing.JoinableQueue() data=[] p = multiprocessing.Process(target=helper, args=(queue,data)) p.start() print('pid is %s,alive=%s',(p.pid,p.is_alive())) for i in range(1,5): data.append(i) queue.put("*"*i) print('begin to join') queue.join() print('consumer process over,begin to kill') # time.sleep(60) #TODO # print('over join,begin to kill') ##p.terminate() os.kill(p.pid, signal.SIGTERM) print('kill over') while p.is_alive(): #这个循环判断可以被p.join()代替 print('still alive') time.sleep(1) print('alive is false') if __name__ == '__main__': make_pro()
根据下图的输出可以,一般的list不能用于进程间通信,若子进程实现了signal.SIGTERM的处理方法,则通过signal.SIGTERM可以使子进程优雅的退出,若子进程没有实现处理
signal.SIGTERM的方法,进程按默认方式退出
=====================面向对象
import os,sys import time import signal import multiprocessing class multi_process(multiprocessing.Process): def __init__(self,task_queue): self.task_queue=task_queue super(multi_process,self).__init__() signal.signal(signal.SIGTERM, self.signal_handler) def signal_handler(self,signum, frame): print("son,Killing subprocess") sys.exit() def run(self): while True: print("son,I am working,id=%s"%(os.getpid())) command = self.task_queue.get() print('son,my command is',command) time.sleep(2) self.task_queue.task_done() def make_pro(): task_queue = multiprocessing.JoinableQueue() data=[] p = multi_process(task_queue) p.start() print('pid is %s,alive=%s',(p.pid,p.is_alive())) for i in range(1,5): data.append(i) task_queue.put("*"*i) print('begin to join') task_queue.join() print('consumer process over,begin to kill') # time.sleep(60) #TODO # print('over join,begin to kill') ##p.terminate() os.kill(p.pid, signal.SIGTERM) print('kill over')
#下面这三句可以用p.join()代替 while p.is_alive(): print('still alive') time.sleep(1) print('alive is false') if __name__ == '__main__': make_pro()
===================
multiprocessing的核心机制是fork,重开一个进程,会将父进程加载过的模块重新加载一遍,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程)
subprocess适用于与外部程序交互,调用外部进程
subprocess 用来执行外部命令,是os.fork() 和 os.execve() 的封装,即先fork一个子进程,再运行新的外部程序,子进程不会把父进程的模块加载一遍;
而multiprocessing的原理是fork,fork()调用:调用1次,返回两次--操作系统自动把当前进程(父进程)复制了一份(子进程),然后,分别在父进程和子进程内返回,父进程返回子进程的pid,子进程返回0,即父进程和子进程都在运行。
对于外部调用来说,使用multiprocessing太占资源
subprocess.Popen()父进程开启子进程后,不管其是否结束,直接执行下一步;
subprocess.Call()父进程一直等待到子进程运行结束,再执行下一步
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2019-03-30 一个人工智能教程,教案接地气、限制级。 http://www.captainbed.net