进程,join的使用,守护进程---day30
1.进程
# ### 进程 import os,time #当前进程id(子进程) res = os.getpid() print(res) #1772 #当前进程id(父进程) res = os.getppid print(res) #1772 #(1) 进程的基本语法 from multiprocessing import Process #先导入这个模块 ''' process 创建子进程,返回进程的对象p target 指定要执行的任务 #后面接函数名 args 指定传递的参数,args的类似时元组,多个参数之间用逗号隔开 ''' def func(): print("1.子进程id>>>>{} , 2.父进程id>>>>{}".format(os.getpid(),os.getppid())) #windows里面下面这句话必须要加: if __name__ == '__main__': print("3.子进程id>>>>{} , 4.父进程id>>>>{}".format(os.getpid(),os.getppid())) #创建子进程,返回一个进程对象,执行func任务 p = Process(target=func) #target指定任务 #调用子进程 p.start() ''' 3.子进程id>>>>1640 , 4.父进程id>>>>6952 1.子进程id>>>>6636 , 2.父进程id>>>>1640 ''' #(2) 创建带有参数的过程 def func(n): for i in range(1,n+1): print("3.子进程id>>>>{} , 4.父进程id>>>>{}".format(os.getpid(),os.getppid())) if __name__ == '__main__': print("1.子进程id>>>>{} , 2.父进程id>>>>{}".format(os.getpid(),os.getppid())) n = 5 #创建子进程 p = Process(target=func,args=(n,)) #调用子进程 p.start() for i in range(1,n+1): print('*' * i) #当程序运行到创建子进程的时候,创建空间会阻塞,然后就会先运行下面的for循环 #等到创建子进程变成就绪的时候再回去执行创建子进程的程序 ''' 运行结果: 1.子进程id>>>>4556 , 2.父进程id>>>>6952 * ** *** **** ***** 3.子进程id>>>>5276 , 4.父进程id>>>>4556 3.子进程id>>>>5276 , 4.父进程id>>>>4556 3.子进程id>>>>5276 , 4.父进程id>>>>4556 3.子进程id>>>>5276 , 4.父进程id>>>>4556 3.子进程id>>>>5276 , 4.父进程id>>>>4556 ''' #(3) 进程之间的数据隔离 count = 100 def func(): global count count += 1 print('我是子进程count={}'.format(count)) if __name__ == '__main__': p = Process(target=func) p.start() time.sleep(1) print(count) ''' 运行结果: 我是子进程count=101 100 说明子进程和主进程之间的数据是隔离的 ''' #(4) 多个进程可以异步并发,子父进程之间的关系 ''' 程序在异步并发任务时,因为cpu调度策略问题,不一定先执行谁或者后执行谁 整体而言,主进程速度快于子进程,cpu遇到阻塞立刻切换其他任务,等到进程的就绪状态在切换回来 #主进程会默认等到所有的子进程执行结束之后,再关闭程序,释放资源 若不等待,子进程并不方便管理,容易造成僵尸进程,在后台不停的占用资源(cpu和内存),不清楚进程的来源 ''' def func(args): print("3.子进程id>>>>{} , 4.父进程id>>>>{}".format(os.getpid(),os.getppid()) , args) if __name__ == '__main__': for i in range(1,11): Process(target=func,args=(i,)).start() print('主程序执行结束...') ''' 运行结果: 执行顺序每次都不一样 3.子进程id>>>>4512 , 4.父进程id>>>>6796 3 3.子进程id>>>>5300 , 4.父进程id>>>>6796 2 3.子进程id>>>>1712 , 4.父进程id>>>>6796 4 主程序执行结束... 3.子进程id>>>>6644 , 4.父进程id>>>>6796 7 3.子进程id>>>>4636 , 4.父进程id>>>>6796 6 3.子进程id>>>>7120 , 4.父进程id>>>>6796 5 3.子进程id>>>>5732 , 4.父进程id>>>>6796 1 3.子进程id>>>>1952 , 4.父进程id>>>>6796 8 3.子进程id>>>>6728 , 4.父进程id>>>>6796 10 3.子进程id>>>>4632 , 4.父进程id>>>>6796 9 '''
2.join
# ### 1.join 等待所有子进程全部执行完毕之后,主进程任务在继续执行(用来同步子父进程速度的) from multiprocessing import Process import os #(1) join的基本语法 def func(): print('发送第一封邮件') if __name__ == '__main__': p = Process(target=func) p.start() #必须等到子进程结束之后再继续执行主程序的代码,用来同步代码的一致性 p.join() print('发送第二封邮件') ''' 运行结果: 发送第一封邮件 发送第二封邮件 ''' #(2) 多个子进程配合join使用 def func(index): print('发送第%s封邮件'%(index)) if __name__ == '__main__': lst = [] for i in range(10): p = Process(target=func,args=(i,)) p.start() lst.append(p) #p.join() #在这边加join时,程序会变成同步阻塞减慢速度 for i in lst: print(i) i.join() print('主进程发最后一封邮件,里面的内容是我发完了') ''' 运行结果: 发送第1封邮件 发送第2封邮件 发送第0封邮件 发送第4封邮件 发送第5封邮件 发送第3封邮件 发送第6封邮件 <Process(Process-1, stopped)> <Process(Process-2, stopped)> <Process(Process-3, stopped)> <Process(Process-4, started)> <Process(Process-5, stopped)> <Process(Process-6, stopped)> <Process(Process-7, started)> <Process(Process-8, started)> 发送第8封邮件 发送第7封邮件 <Process(Process-9, stopped)> <Process(Process-10, started)> 发送第9封邮件 主进程发最后一封邮件,里面的内容是我发完了 ''' # ### 使用自定义类的方式创建进程(拓展) ''' 自定义类创建进程要求: (1) 必须继承Process这个父类 (2) 所有进程执行任务的逻辑要写run方法里面 ''' #(1) 基本语法 class MyProcess(Process): def run(self): print("1.子进程id>>>>{} , 2.父进程id>>>>{}".format(os.getpid(),os.getppid())) if __name__ == '__main__': p = MyProcess() p.start() print("3.子进程id>>>>{} , 4.父进程id>>>>{}".format(os.getpid(),os.getppid())) ''' 运行结果 3.子进程id>>>>4976 , 4.父进程id>>>>6952 1.子进程id>>>>484 , 2.父进程id>>>>4976 ''' #(2) 有参数的进程函数 class MyProcess(Process): def __init__(self,arg): #手动调用一下父类的构造方法(实现进程的创建) super().__init__() self.arg = arg def run(self): print("1.子进程id>>>>{} , 2.父进程id>>>>{}".format(os.getpid(),os.getppid()),self.arg) if __name__ == '__main__': p = MyProcess('我是参数') p.start() print("3.子进程id>>>>{} , 4.父进程id>>>>{}".format(os.getpid(),os.getppid())) 运行结果: 3.子进程id>>>>1412 , 4.父进程id>>>>6952 1.子进程id>>>>2140 , 2.父进程id>>>>1412 我是参数
3.守护进程
# ### 守护进程 ''' 守护进程守护的是主进程,如果主进程执行结束了,意味着守护进程的寿命立刻终止,立刻杀死 语法: 进程.daemon = True 设置当前进程为守护进程 必须写在start()调用进程之前进行设置 默认情况下,主进程会等待所有子进程执行完毕之后,关闭程序,释放资源 守护进程在主进程代码执行结束之后,直接杀掉 ''' from multiprocessing import Process #(1) 基本语法 def func(): print('start 当前子进程') print('end 当前子进程') if __name__ == '__main__': p = Process(target=func) p.daemon = True p.start() print('主进程执行结束...') ''' 运行结果: 主进程执行结束... #首先开辟子进程空间的时候会阻塞,然后就先执行主程序执行结束, #一旦主程序执行结束就表示剩下的全部杀掉不执行 ''' #(2) 多个子进程的场景 import time def func1(): count = 1 while True: print('*'*count) time.sleep(0.5) count += 1 def func2(): print('start func2当前子进程') time.sleep(2) print('end func2当前子进程') if __name__ == '__main__': p1 = Process(target=func1) p2 = Process(target=func2) #设置当前进程为守护进程 p1.daemon =True p1.start() p2.start() time.sleep(1) #非守护进程,主进程还是会默认等待的 print('主程序代码结束') ''' 运行结果 * start func2当前子进程 ** 主程序代码结束... end func2当前子进程 p1和p2都会创建子进程空间,然后运行p1和p2子进程中的程序 然后因为开辟空间的时候会有阻塞,因为不会等到p1和p2全部执行结束后才去执行主程序 此时执行主程序,主程序和p1绑定为守护程序,所以主程序执行完毕就表示p1要全部结束 此时p2在前面睡了2秒,正好p1和主程序都结束了,然后执行p2 ''' #(3) 守护进程的实际用途:监控报活 import time #监控报活 def alive(): while True: print("给监控服务器发消息, 当前5号服务器功能正常 i am ok ~") time.sleep(1) #当前服务器正常完成的功能 def func(): #while True: time.sleep(5) print("当前5号服务器功能,统计财务报表~") if __name__ == '__main__': p1 = Process(target=func) p2 = Process(target=alive) p2.daemon = True p1.start() p2.start() #等待p1子进程执行结束之后,下面的主程序的代码才会执行 p1.join() print('当前服务器状态:统计账务报表功能异常...') 运行结果: 给监控服务器发消息, 当前5号服务器功能正常 i am ok ~ 给监控服务器发消息, 当前5号服务器功能正常 i am ok ~ 给监控服务器发消息, 当前5号服务器功能正常 i am ok ~ 给监控服务器发消息, 当前5号服务器功能正常 i am ok ~ 给监控服务器发消息, 当前5号服务器功能正常 i am ok ~ 当前5号服务器功能,统计财务报表~ 给监控服务器发消息, 当前5号服务器功能正常 i am ok ~ 当前服务器状态:统计财务报表功能异常... 解析:首先p1p2子进程开辟空间,然后执行对应的程序,因为p1对象用了join,必须要等p1子进程结束 之后才能执行下面的主程序代码,当主程序代码执行结束后,因p2是守护进程,所以此时的p2的所有 进程都要全部杀掉。
-------------------------------------------
个性签名:代码过万,键盘敲烂!!!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!