• Process的几个用法和守护进程


    Process的几个用法和守护进程

    一、Process的 join用法

    话不多说,直接上代码

    join 用法一 ,单进程
    from multiprocessing import Process
    import time
    
    def foo():
        print('子进程 start')
        time.sleep(2)
        print('子进程 end')
    
    if __name__ == '__main__':
        p = Process(target=foo)
        p.start()
        # 核心需求就是想让子进程执行完,再执行主进程的print,time有弊端
        # time.sleep(5)
        p.join()  # 在这阻塞住,主进程等待该子进程结束,然后再往下执行,(了解:内部会调用wait())
        print('主进程')
    
    # join用法二(并发)
    from multiprocessing import Process
    import time
    
    def foo(x):
        print('子进程 start')
        time.sleep(x)
        print('子进程 end')
    
    if __name__ == '__main__':
        p1 = Process(target=foo,args=(1,))
        p2 = Process(target=foo,args=(2,))
        p3 = Process(target=foo,args=(3,))
        start = time.time()
        p1.start()
        p2.start()
        p3.start()  # 这几个相当于并发
        # 核心需求就是想让子进程执行完,再执行主进程的print,time有弊端
        # time.sleep(5)
        p1.join()  # 在这阻塞住,主进程等待该子进程结束,然后再往下执行,(了解:内部会调用wait())
        p2.join()
        p3.join()
        # 总时长:按照最长的时间计算多一点
        end = time.time()
        print(end-start)
        print('主进程')
    
    # join用法三(串行)
    from multiprocessing import Process
    import time
    
    def foo(x):
        print('子进程 start')
        time.sleep(x)
        print('子进程 end')
    
    if __name__ == '__main__':
        p1 = Process(target=foo,args=(1,))
        p2 = Process(target=foo,args=(2,))
        p3 = Process(target=foo,args=(3,))
        start = time.time()
        p1.start()
        p1.join()  # 在这阻塞住,主进程等待该子进程结束,然后再往下执行,(了解:内部会调用wait())
        p2.start()
        p2.join()
        p3.start()  # 这几个相当于并行
        p3.join()
    
        # 核心需求就是想让子进程执行完,再执行主进程的print,time有弊端
        # time.sleep(5)
        # 总时长:按照最长的时间计算多一点
        end = time.time()
        print(end-start)
        print('主进程')
    
    # 优化join用法二
    from multiprocessing import Process
    import time
    
    def foo(x):
        print(f'子进程{x} start')
        time.sleep(x)
        print(f'子进程{x} end')
    
    if __name__ == '__main__':
        start = time.time()
        p_list = []
        for i in range(1,4):
            p = Process(target=foo, args=(i,))
            p.start()
            p_list.append(p)
        for p in p_list:
            p.join()
        end = time.time()
        print(end-start)
        print('主进程')
    

    二、Process的pid和ppid用法

    需要先导入os模块

    站在当前进程的角度:os.getpid()>>>>获取当前进程的pid

    ​ os.getppid()>>>>获取当前进程的父进程的pid

    ​ 子进程对象.pid>>>>获取当前进程的子进程pid

    具体看以下代码

    from multiprocessing import Process,current_process
    import time,os
    def task():
        print('子进程 start')
        print('在子进程中查看自己的pid',current_process().pid) # 在子进程查看自己pid方法一
        print('在子进程中查看自己的pid',os.getpid()) # 在子进程查看自己pid方法二
        print('在子进程中查看父进程的pid',os.getppid())
        time.sleep(2)
        print('子进程 end')
    
    if __name__ == '__main__':
        p = Process(target=task)
        p.start()
        print('在主进程查看子进程的pid',p.pid)  # 获取pid,一定要写在start()之后
        print('主进程的pid',os.getpid())
        print('主进程的父进程pid',os.getppid())
        print('主进程')
    

    在主进程查看子进程的pid 1928
    主进程的pid 2900
    主进程的父进程pid 1008
    主进程
    子进程 start
    在子进程中查看自己的pid 1928
    在子进程中查看自己的pid 1928
    在子进程中查看父进程的pid 2900
    子进程 end

    三、Process的name用法

    这是用来查看进程名的

    from multiprocessing import Process,current_process
    import time
    def foo():
        print('子进程 start')
        print('>>>>',current_process().name)  # 获取当前进程名
        time.sleep(2)
        print('子进程 end')
    
    if __name__ == '__main__':
        p = Process(target=foo)
        p.start()
        print(p.name)   
    

    Process-1
    子进程 start

    Process-1
    子进程 end

    四、Process的is_alive的用法

    用来判断进程是否活着,结果是True或False

    from multiprocessing import Process,current_process
    import time
    def foo():
        print('子进程 start')
        time.sleep(2)
        print('子进程 end')
    
    if __name__ == '__main__':
        p = Process(target=foo)
        p.start()
        print(p.is_alive())  # 没运行完就活着 True
        time.sleep(5)
        print(p.is_alive())  # 代码运行完了就算死了 False
        print('主进程')
    

    True
    子进程 start
    子进程 end
    False
    主进程

    五、Process的terminate用法

    用来直接把进程终止(死掉)

    from multiprocessing import Process,current_process
    import time
    def foo():
        print('子进程 start')
        time.sleep(50)
        print('子进程 end')
    
    if __name__ == '__main__':
        p = Process(target=foo)
        p.start()
        p.terminate()  # 给操作系统发了一个终止进程的请求
        print(p.is_alive())  # 没运行完就活着 True
        p.join()  # 可以不等50秒,直接执行下面的
        print(p.is_alive())
    
        print('主进程')
    

    True
    False
    主进程

    六、守护进程

    守护进程本质也是一个子进程,主进程的代码执行完毕,守护进程就直接结束

    from multiprocessing import Process
    import time
    def foo():
        print('守护进程 start')
        time.sleep(10)
        print('守护进程 end')
    
    if __name__ == '__main__':
        p = Process(target=foo)
        p.daemon = True  # 把这个子进程定义为了守护进程,只陪伴到打印主进程就结束
        p.start()
    
        print('主进程')  # 这个执行完,主进程的代码就执行完毕,子进程就直接结束,
    

    主进程

    七、抢票小程序

    
    from multiprocessing import Process
    import json,time,os
    def search():
        time.sleep(1)
        with open('db',mode='rt',encoding='utf-8') as fr:
            res = json.load(fr)
            print(f'还剩{res["count"]}张')
    
    def get():
        with open('db',mode='rt',encoding='utf-8') as fr:
            res = json.load(fr)
        time.sleep(1) # 模拟网络io
        if res['count'] > 0:
            res['count'] -= 1
            with open('db',mode='wt',encoding='utf-8') as fw:
                json.dump(res,fw)
                time.sleep(1.5)  # 模拟网络io
                print(f'进程{os.getpid()}抢票成功')
        else:
            print('票已售罄!!!')
    
    def task():
        search()
        get()
    
    if __name__ == '__main__':
        for i in range(15):
            p = Process(target=task)
            p.start()
            p.join()
    
    # 为了保证数据的安全,要牺牲掉效率
    
  • 相关阅读:
    ActiveReports 9实战教程(1): 手把手搭建环境Visual Studio 2013 社区版
    分享产品发布的10条经验
    Mobile first! Wijmo 5 + Ionic Framework之:Hello World!
    Java知识回顾 (14)网络编程
    Java知识回顾 (13)序列化
    idea下java项目的打包与使用
    Java知识回顾 (12) package
    Java知识回顾 (11) 异常处理
    创建表时 ORA-00955: 名称已由现有对象使用
    工作笔记—hibernate之QueryCriteria
  • 原文地址:https://www.cnblogs.com/zhuangyl23/p/11515426.html
Copyright © 2020-2023  润新知