Python进程的作用是什么,如何创建进程
Admin 2022-09-30 群英技术资讯 324 次浏览
它们的主要作用:多任务同时执行
Windows打开的程序就是一个进程例如打开qq 打开微信
如果打开2个qq代表打开了2个进程
只能Linux 使用os.fork()用这个可以创建多进程
Linux/Windows使用multiprocessing模块和Pool进程池(他俩是跨平台模块)
from multiprocessing import Process #从multiprocessing库中导入Process模块 #执行进程代码 #一个子进程 def test(interval): print("我是一个子进程") #执行主程序 def main(): print("主进程启动") p = Process(target=test,args=(1,)) #使用进程模块,目标参数target为子进程函数 p.start() #启动子进程 print("主进程结束") if __name__ == '__main__': main() """ >>> runfile('D:/python_files/python_fiew/网络编程_01.py', wdir='D:/python_files/python_fiew') 主进程启动 主进程结束 我是一个子进程 """
from multiprocessing import Process import time,os #子进程1 def child_1(interval): print("子进程(%s)开始执行,父进程为(%s)"%(os.getpid(),os.getpid())) #os.getpid()为获取进程号 t_stat = time.time() #计时开始 time.sleep(interval) #程序将被挂起n秒 t_end = time.time() #计时结束 print("子进程(%s)的执行时间为'%0.2f'秒"%(os.getpid(),t_end-t_stat)) #子进程2 def chlid_2(interval): print("子进程(%s)开始执行,父进程为(%s)"%(os.getpid(),os.getpid())) t_stat = time.time() time.sleep(interval) t_end = time.time() print("子进程(%s)的执行时间为(%0.2f)"%(os.getpid(),t_end-t_stat)) if __name__ == '__main__': print("-----父进程开始执行-------") print("父进程启动时,父进程PID为:(%s)"%(os.getpid())) #打印父进程启动时父进程的PID p1 = Process(target=child_1,args=(1,)) #实例化子进程1 p2 = Process(target=chlid_2,args=(1,)) #实例化子进程2 p1.start() #启动子进程1 p2.start() #启动子进程2 #此时父进程仍然在执行 print("pi.is_alive=%s"%(p1.is_alive())) #p1.is_alive() 判断子进程p1是否还在执行,执行则返回ture print("p2_is_alive=%s"%(p2.is_alive())) #输出此时进程执行过程中的PID(进程号) print("执行过程中的p1的进程号p1.pid=%s"%(p1.pid)) print("执行过程中的p2的进程号p2.pid=%s" % (p2.pid)) print("---等待子进程结束----") p1.join() #等待子程序p1结束 p2.join() print("父进程结束,此时父进程的进程号为:(%s)"%(os.getpid())) #总结:#os.getpid()为获取进程号 #p1.is_alive() 判断子进程p1是否还在执行,执行则返回ture
由运行结果分析:子进程在执行的过程中,进程号不变。父进程号在启动时,和在结束所有子进程时 相同,而当子进程同时执行时,父进程号会动态变化。
挂起进程在 操作系统中可以定义为暂时被淘汰出 内存的进程,机器的资源是有限的,在资源不足的情况下,操作系统对在内存中的程序进行合理的安排,其中有的进程被暂时调离出内存,当条件允许的时候,会被操作系统再次调回内存,重新进入等待被执行的状态即就绪态,系统在超过一定的时间没有任何动作。
(解决上一个程序中两个子进程重复代码的问题)
from multiprocessing import Processimport time,os#继承Process类class SubProcess(Process): def __init__(self,interval,name=""): #子类SubProcess的构造方法 Process.__init__(self) #Process.__init__(self) #继承父类的构造方法 self.interval = interval self.name = name #重写父类方法 def run(self): print("子进程(%s)开始执行,父进程为(%s)" % (os.getpid(), os.getpid())) # os.getpid()为获取进程号 t_stat = time.time() # 计时开始 time.sleep(self.interval) # 程序将被挂起n秒 t_end = time.time() # 计时结束 print("子进程(%s)的执行时间为'%0.2f'秒" % (os.getpid(), t_end - t_stat))if __name__ == '__main__': print("-----父进程开始执行-------") print("父进程启动时,父进程PID为:(%s)"%(os.getpid())) #打印父进程启动时父进程的PID p1 = SubProcess(interval=1,name='ZARD1') #实例化子进程1 p2 = SubProcess(interval=2,name=('ZARD2')) #实例化子进程2 p1.start() #启动子进程1 p2.start() #启动子进程2 #此时父进程仍然在执行 print("pi.is_alive=%s"%(p1.is_alive())) #p1.is_alive() 判断子进程p1是否还在执行,执行则返回ture print("p2_is_alive=%s"%(p2.is_alive())) #输出此时进程执行过程中的PID(进程号) print("p1.name = %s"%(p1.name)) print("执行过程中的p1的进程号p1.pid=%s"%(p1.pid)) print("p2.name = %s" % (p2.name)) print("执行过程中的p2的进程号p2.pid=%s" % (p2.pid)) print("---等待子进程结束----") p1.join() #等待子程序p1结束 p2.join() print("父进程结束,此时父进程的进程号为:(%s)"%(os.getpid()))from multiprocessing import Process import time,os #继承Process类 class SubProcess(Process): def __init__(self,interval,name=""): #子类SubProcess的构造方法 Process.__init__(self) #Process.__init__(self) #继承父类的构造方法 self.interval = interval self.name = name #重写父类方法 def run(self): print("子进程(%s)开始执行,父进程为(%s)" % (os.getpid(), os.getpid())) # os.getpid()为获取进程号 t_stat = time.time() # 计时开始 time.sleep(self.interval) # 程序将被挂起n秒 t_end = time.time() # 计时结束 print("子进程(%s)的执行时间为'%0.2f'秒" % (os.getpid(), t_end - t_stat)) if __name__ == '__main__': print("-----父进程开始执行-------") print("父进程启动时,父进程PID为:(%s)"%(os.getpid())) #打印父进程启动时父进程的PID p1 = SubProcess(interval=1,name='ZARD1') #实例化子进程1 p2 = SubProcess(interval=2,name=('ZARD2')) #实例化子进程2 p1.start() #启动子进程1 p2.start() #启动子进程2 #此时父进程仍然在执行 print("pi.is_alive=%s"%(p1.is_alive())) #p1.is_alive() 判断子进程p1是否还在执行,执行则返回ture print("p2_is_alive=%s"%(p2.is_alive())) #输出此时进程执行过程中的PID(进程号) print("p1.name = %s"%(p1.name)) print("执行过程中的p1的进程号p1.pid=%s"%(p1.pid)) print("p2.name = %s" % (p2.name)) print("执行过程中的p2的进程号p2.pid=%s" % (p2.pid)) print("---等待子进程结束----") p1.join() #等待子程序p1结束 p2.join() print("父进程结束,此时父进程的进程号为:(%s)"%(os.getpid()))
代码分析:
(解决当要创造成百上千个进程的情况)
例子: 有三个水槽 ,要接10桶水,我们最多只能同时接3盆,第10盆随便找一个盆,其他两个闲置。
from multiprocessing import Pool #导入进程池 import os,time def task(name): print("子进程(%s)执行task %s..."%(os.getpid(),name)) time.sleep(2) #休眠2秒 if __name__ == '__main__': print("---父进程(%s)启动---"%(os.getpid())) p = Pool(3) #定义一个进程池,一次最多容纳三个进程,即一次最多可同时执行三个子进程 for i in range(10): p.apply_async(task,args=(i,)) #使用非阻塞的方式调用task print("---等待所有子进程结束---") p.close() #关闭进程池,关闭后进程池不再接收新的请求 p.join() #等待子进程结束 print("全部子进程结束")
小结:定义一个进程池,并规定一个池子中可以同时执行多少个进程,可以实现多个进程分批次的执行。
注意:
(1)区分使用Process模块与使用进程池模块Pool的区别
(2)对于实例对象 p,p.start()表示开始执行进程;p.join()表示结束进程
(3)注意加强阻塞与非阻塞知识点的学习
引例:
from multiprocessing import Process #子进程1 def plus(): print("---子进程1开始执行---") global g_num #声明全局变量 g_num += 50 print("在子进程1下:g_num = %d"%(g_num)) print("---子进程1结束运行---") #子进程2 def minus(): print("---子进程2开始执行---") global g_num #声明全局变量 g_num -= 50 print("在子进程2下:g_num = %d"%(g_num)) print("---子进程2结束运行---") g_num = 100 #赋值全局变量 if __name__ == '__main__': print("---主进程启动---") print("在主进程运行中,g_num = %d"%(g_num)) child1 = Process(target=plus) #实例化子进程1 child2 = Process(target=minus) # 实例化子进程2 child1.start() #启动子进程1 child2.start() child1.join() #等待子进程结束 child2.join() print("---主进程结束---")
由以上例子可见,对于进程1,2而言,全局变量g_num并不互相影响。即有如下关系:
那么就有如下问题了,思考:如何才能实现进程之间的通讯?
答:通过 multiprocessing Queue(队列), Pipes(管道), 接下来主要演示 Queue(队列)模块。
1.新来的排队的在队尾
2.最前面的完成离队后,后面一个跟上
多进程队列的使用Queue, 本身他就是一个消息队列程序 :
实践: 当Queue(3)时:
from multiprocessing import Queue #导入队列模块 if __name__ == '__main__': q = Queue(3) #初始化一个Queue对象,最多只能接受3条put信息 #消息写入队列 q.put("消息1") #将此消息1写入队列 q.put("消息2") print(q.full()) #q.full() 是验证队列是否已满 没满则返回False q.put("消息3") #将此消息3写入队列 print(q.full()) #q.full() 是验证队列是否已满 满了则返回Ture #利用try看看队列已满是否还可再塞入信息 try: q.put("尝试塞入第4条信息",True,1) #可能出问题的代码 except: print("尝试利用q.put()向队列中继续添加信息:") print("队列已满,现有消息数量为:%d,无法继续添加信息。"%(q.qsize())) #q.qsize() 返回队列中的已有信息数量 try: q.put_nowait("尝试塞入第4条信息") # 可能出问题的代码 except: print("尝试利用q.put_nowait()向队列中继续添加信息:") print("队列已满,现有消息数量为:%d,无法继续添加信息。" % (q.qsize())) # q.qsize() 返回队列中的已有信息数量 #获取(打印)队列中的信息 if not q.empty(): print("---从队列中读取信息---") for i in range(q.qsize()): #循环打印队列信息 print(q.get_nowait()) #q.get_nowait() 读取队列信息
解决:
当Queue(4)时,打印的结果如下,可见此时可继续向队列中塞入第4条信息。
小结:
multiprocessing.Process 可以创建多进程,使用multiprocessing Queue可以实现队列操作。
from multiprocessing import Process,Queue import time #子进程1:向队列中写入数据 def write_date(q): if not q.full(): #若队列没满,则写入数据 for i in range(5): date = "数据" + str(i) q.put(date) #向队列中写入数据 print("已写入:%s" % date) #子进程2:向队列中读取数据 def read_date(q): time.sleep(1) # 休眠1s while not q.empty(): print("读取:%s" % q.get(True, 2)) # 等待2s,如果还没读取到消息,抛出异常 #主程序 if __name__ == '__main__': print("---主程序启动---") q = Queue() # 父进程创建Queue,并传给各个子进程 write_child = Process(target=write_date,args=(q,)) # 实例化进程对象,其中args=(q,)表示把队列传给子进程1 read_child = Process(target=read_date,args=(q,)) write_child.start() # 启动子进程1,写入 read_child.start() # 启动子进程2,读取 write_child.join() # 等待子进程1结束 read_child.join() # 等待子进程2结束 print('-----父进程结束-----')
小结:
(1)进程之间可以通过队列来实现通信,但需要注意的是,队列中的信息遵循“先进先出”的原则。如上数据那样,先写入数据0,则最先读出的数据也是数据0;
(2)如:
在父进程中创建队列,再利用Process模块实例化子进程对象,target参数为子进程的函数名,args参数即为队列。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
本篇文章给大家带来了关于Python的相关知识,Python 在 3.7 的时候引入了一个模块:contextvars,从名字上很容易看出它指的是上下文变量,下面就来和大家详细讲讲如何使用contextvars实现管理上下文变量,希望对大家有帮助。
随机整数:>>>importrandom>>>random randint(0,99)21随机选取0到100间的偶数:>>>importrandom>>>random randrange(0,101,2)42随机浮点数
在可视化数据时,通常需要在单个图形中绘制多个图形。 例如,如果您想从不同的角度可视化相同的变量如:数字变量的并排直方图和箱线图,则多个图形很有用。 在这篇文章中,我分享了绘制多个图形的 4 个简单但实用的技巧,具有一定的参考价值,需要的小伙伴可以参考一下
python 如何实现给图片加水印?我们在一些网站或者软件上,上传或者发布图片的时候,会看到图片被自动添加上了水印,那么这是怎么样实现的呢?下面小编就给大家分享使用Python实现给图片指定位置添加水印的方法,感兴趣的朋友就继续往下看吧。
python staticmethod 返回类,函数的静态方法。该方法不强制要求传递参数,如下声明一个静态方法:以上实例声明了静态方法 f,从而可以实现实例化使用 C().f(),当然也可以不实例化调用该方法 C.f()。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008