zoukankan      html  css  js  c++  java
  • 3 并发编程-(进程)-join方法

    1、查看当前进程的进程号getpid() 和 其父 进程号 getppid()

    # 查看进程的pid
    from multiprocessing import Process
    import time,os
    def task():
        print(f"{os.getpid()} is running ; parent id is {os.getppid()}")
        time.sleep(3)
        print(f"{os.getpid()} is done")
    if __name__ == '__main__':
        p = Process(target=task,)
        p.start()
        # 第一个是当前的主程序,第二个是pycharm主程序
        print('',os.getpid(),os.getppid())# 获得当前进程的进程号

     window下:

    2、Process对象的join方法

    p.join主线程等待P终止(主线程处于等待的状态,而p处于运行的状态)

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

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

    情况二:如果主进程的任务在执行到某一个阶段时,需要等待子进程执行完毕后才能继续执行,就需要有一种机制能够让主进程检测子进程是否运行完毕

    在子进程执行完毕后才继续执行,否则一直在原地阻塞,这就是join方法的作用

    2.1、join方法 之 并发执行

    from multiprocessing import Process
    import time,os
    def task(name):
        print(f"{name} is running")
        time.sleep(3)
        print(f"{name} is done")
    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()
    
        p1.join()# 让主进程等
        p2.join()
        p3.join()
        # 第一个是当前的主程序,第二个是pycharm主程序
        print('',os.getpid(),os.getppid())# 获得当前进程的进程号

    子进程1 is running
    子进程2 is running
    子进程3 is running
    子进程1 is done
    子进程2 is done
    子进程3 is done
    主 3432 5956

    2.2、join方法 之 串行执行

    from multiprocessing import Process
    import time,os
    def task(name):
        print(f"{name} is running")
        time.sleep(3)
        print(f"{name} is done")
    if __name__ == '__main__':
        p1 = Process(target=task,args=('子进程1',))
        p2 = Process(target=task, args=('子进程2',))
        p3 = Process(target=task,args=('子进程3',) )
    
        p1.start() # 仅仅发送信号
        p1.join()
        p2.start()
        p2.join()  
        p3.start()
        p3.join()
        # 第一个是当前的主程序,第二个是pycharm主程序
        print('',os.getpid(),os.getppid())# 获得当前进程的进程号

    子进程1 is running
    子进程1 is done
    子进程2 is running
    子进程2 is done
    子进程3 is running
    子进程3 is done
    主 2084 6900

    详细解析如下:

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

    而我们p1.join()是在等p1结束,没错p1只要不结束主线程就会一直卡在原地,这也是问题的关键

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

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

    上述启动进程与join进程可以简写为

    p_l=[p1,p2,p3,p4]
    
    for p in p_l:
        p.start()
    
    for p in p_l:
        p.join()

     3、Process对象的其他属性或方法 terminate/is_alive  name/pid

    p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该进程方法需要特别小心

    如果p还保存了一个锁那么也将不会被释放,进而导致死锁

    p.is_alive():如果仍然运行,返回True  否则 False

    p.name:进程的名称

    p.pid:进程的pid

    from multiprocessing import Process
    import time
    import random
    
    def task(name):
        print('%s is piaoing' %name)
        time.sleep(random.randrange(1,5))
        print('%s is piao end' %name)
    
    if __name__ == '__main__':
        p1=Process(target=task,args=('egon',),name='子进程1') #可以用关键参数来指定进程名
        p1.start()
    
        print(p1.name,p1.pid,)
    View Code

    4、练习题--效果1、2属于并发;效果3属于串行

    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

    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')
    View Code

    效果二:保证最后输出-------->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,))
    
        p1.start()
        p2.start()
        p3.start()
        p1.join()
        p2.join()
        p3.join()
        print('-------->4')
    View Code

    效果三:保证按顺序输出

    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()
        p1.join()
        p2.start()
        p2.join()
        p3.start()
        p3.join()
        print('-------->4')
    View Code
  • 相关阅读:
    解决windows 下Java编译和运行版本不一致的错误has been compiled by a more recent version
    解决两个OpenCV 报错 (raise.c and GTK) ,重新安装和编译
    Java|如何使用“Java”爬取电话号码(转载)
    Java手机号码工具类(判断运营商、获取归属地)以及简要的原理跟踪(转载)
    Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
    mysql分库分表
    python将html文件转换为pdf
    mysql获取字段名和对应的注释
    mysql大表查询慢对应方案
    harbor安装
  • 原文地址:https://www.cnblogs.com/foremostxl/p/9726956.html
Copyright © 2011-2022 走看看