• Process对象的其它方法与属性(join)


    一 Process对象的join方法

    在主进程运行过程中如果想并发地执行其他的任务,我们可以开启子进程,此时主进程的任务与子进程的任务分两种情况

    情况一:在主进程的任务与子进程的任务彼此独立的情况下,主进程的任务先执行完毕后,主进程还需要等待子进程执行完毕,然后统一回收资源。

    情况二:如果主进程的任务在执行到某一个阶段时,需要等待子进程执行完毕后才能继续执行,就需要有一种机制能够让主进程检测子进程是否运行完毕,在子进程执行完毕后才继续执行,否则一直在原地阻塞,这就是join方法的作用

    # join方法
    from multiprocessing import Process
    import time
    import os
    
    
    def task(name):                                                               # os.getppid()查看父进程编号
        print("%s is running, parent id is <%s>" % (os.getpid(), os.getppid()))   # os.getpid()查看自己进程编号
        time.sleep(3)   # 模拟任务运行一段时间
        print("%s is done, parent id is <%s>" % (os.getpid(), os.getppid()))
    
    
    if __name__ == "__main__":    # windows 一定要把开启指令放到main下面  Linux无所谓
        # Process(target=task, kargs={"name" : "子进程"})  # 方式1
        p = Process(target=task, args=("子进程1",))  # 方式2  实例化得到一个对象
        p.start()    # (仅仅只是给操作系统发送了一个信号)开启子进程,帮你执行task
    
        p.join()  # 主进程会等子进程运行(主进程基于子进程执行的结果进行后续代码的执行)
        print("主", os.getpid(), os.getppid())  # 此时的父进程是pycharm
        print(p.pid)   # p对象下的pid(验证僵尸进程)

    10952 is running, parent id is <8624>
    10952 is done, parent id is <8624>
    主 8624 124
    10952

    from multiprocessing import Process
    import time
    import os
    
    
    def task(name, n):                                                               # os.getppid()查看父进程编号
        print("%s is running" % name)   # os.getpid()查看自己进程编号
        time.sleep(n)   # 模拟任务运行一段时间
    
    
    if __name__ == "__main__":    # windows 一定要把开启指令放到main下面  Linux无所谓
        start = time.time()
        p1 = Process(target=task, args=("子进程1", 5))
        p2 = Process(target=task, args=("子进程2", 3))
        p3 = Process(target=task, args=("子进程3", 2))
        p_l = [p1, p2, p3]
    
        # p1.start()    # (仅仅只是给操作系统发送了一个信号)开启子进程,帮你执行task(不一定按顺序)
        # p2.start()
        # p3.start()
        for i in p_l:   # 简写
            i.start()
    
        # p1.join()     # 让主进程等,连续三个并发执行
        # p2.join()
        # p3.join()
        for p in p_l:
            p.join()
    
        print("主", (time.time()-start))  # 此时的父进程是pycharm

    子进程1 is running
    子进程2 is running
    子进程3 is running
    主 5.103978633880615

    注意:

    进程只要start就会在开始运行了,所以p1-p3.start()时,系统中已经有并发的进程了

    join是让主线程等,而p1-p3仍然是并发执行的,p1.join的时候,其余p2,p3,p4仍然在运行,等#p1.join结束,可能p2,p3早已经结束了,这样p2.join,p3.join直接通过检测,无需等待

    所以3个join花费的总时间仍然是耗费时间最长的那个进程运行的时间

    串行

    # 串联执行
    from multiprocessing import Process
    import time
    import os
    
    
    def task(name, n):                                                               # os.getppid()查看父进程编号
        print("%s is running" % name)   # os.getpid()查看自己进程编号
        time.sleep(n)   # 模拟任务运行一段时间
    
    
    if __name__ == "__main__":    # windows 一定要把开启指令放到main下面  Linux无所谓
        start = time.time()
        p1 = Process(target=task, args=("子进程1", 5))
        p2 = Process(target=task, args=("子进程2", 3))
        p3 = Process(target=task, args=("子进程3", 2))
    
        p1.start()    # (仅仅只是给操作系统发送了一个信号)开启子进程,帮你执行task(不一定按顺序)
        p1.join()    # 主程序再等P1
        p2.start()    # p2 才开始
        p2.join()
        p3.start()
        p3.join()
    
        print("主", (time.time()-start))  # 此时的父进程是pycharm 

    子进程1 is running
    子进程2 is running
    子进程3 is running
    主 10.3139066696167


     

    二 Process对象的其他属性或方法

    进程对象的其他方法一:is_alive

    # 了解 p.is_alive()
    from multiprocessing import Process
    import time
    import os
    
    
    def task(name):                                                               # os.getppid()查看父进程编号
        print("%s is running, parent id is <%s>" % (os.getpid(), os.getppid()))   # os.getpid()查看自己进程编号
        time.sleep(3)   # 模拟任务运行一段时间
        print("%s is done, parent id is <%s>" % (os.getpid(), os.getppid()))
    
    
    if __name__ == "__main__":    # windows 一定要把开启指令放到main下面  Linux无所谓
        # Process(target=task, kargs={"name" : "子进程"})  # 方式1
        p = Process(target=task, args=("子进程1",))  # 方式2  实例化得到一个对象
        p.start()    # (仅仅只是给操作系统发送了一个信号)开启子进程,帮你执行task
    
        print(p.is_alive())  # 判断活着还是死的
        p.join()  # 主进程会等子进程运行(主进程基于子进程执行的结果进行后续代码的执行)
        print("主", os.getpid(), os.getppid())  # 此时的父进程是pycharm
        print(p.pid)   # p对象下的pid(验证僵尸进程)
        print(p.is_alive())    # 判断活着还是死的
    

    进程对象的其他属性:terminal

    # 了解 p.terminate()
    from multiprocessing import Process
    import time
    import os
    
    
    def task(name):                                                               # os.getppid()查看父进程编号
        print("%s is running, parent id is <%s>" % (os.getpid(), os.getppid()))   # os.getpid()查看自己进程编号
        time.sleep(3)   # 模拟任务运行一段时间
        print("%s is done, parent id is <%s>" % (os.getpid(), os.getppid()))
    
    
    if __name__ == "__main__":    # windows 一定要把开启指令放到main下面  Linux无所谓
        # Process(target=task, kargs={"name" : "子进程"})  # 方式1
        p = Process(target=task, args=("子进程1",))  # 方式2  实例化得到一个对象
        p.start()    # (仅仅只是给操作系统发送了一个信号)开启子进程,帮你执行task
    
        print("主")
        p.terminate()   # 给操作系统发出信号终止进程
        time.sleep(3)
        print(p.is_alive())
    

    进程对象的其他属性:name

    # 了解 p.name
    from multiprocessing import Process
    import time
    import os
    
    
    def task(name):                                                               # os.getppid()查看父进程编号
        print("%s is running, parent id is <%s>" % (os.getpid(), os.getppid()))   # os.getpid()查看自己进程编号
        time.sleep(3)   # 模拟任务运行一段时间
        print("%s is done, parent id is <%s>" % (os.getpid(), os.getppid()))
    
    
    if __name__ == "__main__":    # windows 一定要把开启指令放到main下面  Linux无所谓
        # Process(target=task, kargs={"name" : "子进程"})  # 方式1
        p = Process(target=task, args=("子进程1",), name="我的进程")  # 方式2  实例化得到一个对象
        p.start()    # (仅仅只是给操作系统发送了一个信号)开启子进程,帮你执行task
    
        print("主")
        print(p.name)  # 查看进程名称(默认为Process-1)
    

    三 练习题

    1、改写下列程序,分别别实现下述打印效果

    from multiprocessing import Process
    import time
    import random
    
    def task(n):
        time.sleep(random.randint(1,3))
        print('-------->%s' %n)
    
    if __name__ == '__main__':
        p1=Process(target=task,args=(1,))
        p2=Process(target=task,args=(2,))
        p3=Process(target=task,args=(3,))
    
        p1.start()
        p2.start()
        p3.start()
    
        print('-------->4')
    

    效果一:保证最先输出-------->4

    -------->4
    -------->1
    -------->3
    -------->2
    from multiprocessing import Process
    import time
    import random
    
    def task(n):
        time.sleep(random.randint(1, 3))
        print('-------->%s' % n)
    
    
    if __name__ == '__main__':
        p1 = Process(target=task, args=(1,))
        p2 = Process(target=task, args=(2,))
        p3 = Process(target=task, args=(3,))
        p_1 = [p1, p2, p3]
    
        for p in p_1:
            p.start()
    
        print('-------->4')

    效果二:保证最后输出-------->4

    -------->2
    -------->3
    -------->1
    -------->4
    from multiprocessing import Process
    import time
    import random
    
    def task(n):
        time.sleep(random.randint(1, 3))
        print('-------->%s' % n)
    
    
    if __name__ == '__main__':
        p1 = Process(target=task, args=(1,))
        p2 = Process(target=task, args=(2,))
        p3 = Process(target=task, args=(3,))
        p_1 = [p1, p2, p3]
    
        for p in p_1:
            p.start()
    
        for p in p_1:
            p.join()
    
        print('-------->4')

    效果三:保证按顺序输出

    -------->1
    -------->2
    -------->3
    -------->4
    from multiprocessing import Process
    import time
    import random
    
    def task(n):
        time.sleep(random.randint(1, 3))
        print('-------->%s' % n)
    
    
    if __name__ == '__main__':
        p1 = Process(target=task, args=(1,))
        p2 = Process(target=task, args=(2,))
        p3 = Process(target=task, args=(3,))
        p_1 = [p1, p2, p3]
    
        for p in p_1:
            p.start()
            p.join()
    
        print('-------->4')

    2、判断上述三种效果,哪种属于并发,哪种属于串行?

    answer

    效果一与效果二,是并发,效果三是串行

  • 相关阅读:
    【Java】 Spring 框架初步学习总结(一)简单实现 IoC 和 AOP
    【Java】MyBatis框架初步学习总结
    CPLEX在Linux上的安装与配置
    CPLEX在IDEA上的配置
    WINDOWS系统下用BAT脚本运行JAR包
    启发式算法:遗传算法 (Genetic algorithm)
    Java基础知识:集合框架
    Java基础知识:Collection接口
    打印n位数的最大值
    我喜欢的博客
  • 原文地址:https://www.cnblogs.com/fantsaymwq/p/10125293.html
Copyright © 2020-2023  润新知