• 进程,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的所有
    进程都要全部杀掉。
  • 相关阅读:
    HDU
    【JZOJ1252】【洛谷P5194】天平【搜索】
    【JZOJ1252】【洛谷P5194】天平【搜索】
    【JZOJ3896】战争游戏【割点】
    【JZOJ3896】战争游戏【割点】
    【JZOJ3895】数字对【ST表】
    【JZOJ3895】数字对【ST表】
    【JZOJ3894】改造二叉树【树】【LIS】
    【JZOJ3894】改造二叉树【树】【LIS】
    【洛谷P4014】【网络流24题】分配问题【费用流】
  • 原文地址:https://www.cnblogs.com/weiweivip666/p/13082451.html
Copyright © 2020-2023  润新知