zoukankan      html  css  js  c++  java
  • python基础-守护进程、守护线程、守护非守护并行

    守护进程

    1、守护子进程

    主进程创建守护进程 
      其一:守护进程会在主进程代码执行结束后就终止 
      其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children

    注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止

    我们来看一个例子

    from multiprocessing import Process
    import os,time,random
    
    def task():
        print('%s is running' %os.getpid())
        time.sleep(2)
        print('%s is done' %os.getpid())
    
        #守护进程内无法再开启子进程,否则抛出异常
        # p = Process(target=time.sleep, args=(3,))
        # p.start()
    
    if __name__ == '__main__':
        p=Process(target=task)
        p.daemon = True #1、必须在p.start()之前
        p.start()
        print('主')
    

    输出结果如下:

    原因是:主进程程序启动执行到p子进程,由于子进程需要开辟内存空间,由于需要耗费时间,所以主进程会首先输出“主”,由于主进程执行完毕,那么守护子进程p也就被干掉了,随之主进程也就退出了 

    如果上面代码修改如下,加上 p.join()这一行代码

    if __name__ == '__main__':
        p=Process(target=task)
        p.daemon = True #1、必须在p.start()之前
        p.start()
        p.join()
        print('主')
    

    那么程序会输出如下:

    14732 is running
    
    14732 is done
    主
    

    join以前也分析过,是起到阻塞作用,子进程执行完毕,才执行主进程,所以加上join 
    1、执行到join,是起到阻塞作用,就会执行子进程,然后执行完毕,在执行主进程 
    2、也可以这样理解,执行到join,由于主进程print(“主”)没有执行完,所以守护进程不会被干掉,继续执行

    1、守护子进程、非守护子进程并存

    在上面的例子是子进程只有一个守护进程,在主进程执行完毕,守护子进程就会被干掉 
    ,我们在来看一个,子进程既有守护子进程,又包含非守护子进程

    from multiprocessing import Process
    from threading import Thread
    import time,os
    def foo():
        print(123)
        time.sleep(1)
        print("end123")
    
    def bar():
    
        print(456)
        time.sleep(3)
        print("end456")
    
    
    if __name__ == '__main__':
        p1=Process(target=foo)
        p2 = Process(target=bar)
    
        p1.daemon=True
        p1.start()
        p2.start()
        print("main-------")
    

    输出如下:

    main-------
    456
    end456
    

    原因如下:由于p1,p2都是子进程,需要开辟内存空间,需要耗费时间,所以会优先输出主进程“main”,由于p1是守护子进程,p2是非守护子进程,当主进程执行完毕(注意之类主进程还没有退出,因为还有p2非守护进程),p1守护进程也就退了,但是还有一个p2非守护进程,所以p2会执行自己的代码任务,当p2执行完毕,那么主进程也就退出了,进而整个程序就退出了

    守护线程

    守护子线程

    无论是进程还是线程,都遵循:守护xxx会等待主xxx运行完毕后被销毁 
    需要强调的是:运行完毕并非终止运行

    1.对主进程来说,运行完毕指的是主进程代码运行完毕 
    2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕

    详细解释: 
    1 主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束,

    2 主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束。

    我们先来看一个例子

    from multiprocessing import Process
    from threading import Thread
    import os,time,random
    
    def task():
        # t=Thread(target=time.sleep,args=(3,))
        # t.start()
        print('%s is running' %os.getpid())
        time.sleep(2)
        print('%s is done' %os.getpid())
    
    if __name__ == '__main__':
        t=Thread(target=task)
        t.daemon = True
        t.start()
        print('')

    输出如下:

    13368 is running
    主

    原因是: 
    在执行到守护子线程t,由于主线程子线程通用一块内存,所以不存在不同进程创建各自空间,所以就先输出子进程的执行任务代码,所以输出print(‘%s is running’ %os.getpid()),由于time.sleep(2),所以就会执行主线程“main”,然后主线程执行完毕,那么即使2秒过后,由于主线程执行完毕,那么子守护线程也就退出了,所以 print(‘%s is done’ %os.getpid())就不会执行了

    守护子线程非守护子进程并存

    我们解析来看一个守护子线程非守护子进程并存的例子

    from threading import Thread
    import time
    def foo():
        print(123)
        time.sleep(1)
        print("end123")
    
    def bar():
        print(456)
        time.sleep(3)
        print("end456")
    
    if __name__ == '__main__':
        t1=Thread(target=foo)
        t2 = Thread(target=bar)
    
        t1.daemon=True
    
        t2.start()
        t1.start()
        print("main-------")
    

    输出如下:

    456
    123
    main-------
    
    end123
    
    end456
    

    原因是: 
    t1是守护子线程,t2非守护子线程,跟主线程使用一块内存,所以会输出t1,t1子线程的任务代码,所以执行456,123由于t1,t2都有睡眠时间,所以执行主线程代码,然后对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕,所以会执行t1,t2睡眠后的任务代码,然后程序退出。 
    我们会问为什么t1守护子线程,也会执行sleep后的代码,不是说主线程代码执行完毕,守护线程就被干掉了吗?这里要注意是对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕,当时t2还没执行完毕

    转自:
    https://blog.csdn.net/u013210620/article/details/78710532
  • 相关阅读:
    Smobiler如何实现.net一键开发,ios和android跨平台运行
    使用Smobiler实现类似美团的界面
    疫情当下,企业系统如何快速实现移动化?
    Smobiler针对百度文字识别SDK动态编译与运行
    smobiler自适应不同手机分辨率
    仓库管理移动应用解决方案——C#开发的移动应用开源解决方案
    移动OA办公——Smobiler第一个开源应用解决方案,快来get吧
    react-native 标题随页面滚动显示和隐藏
    react-native 键盘遮挡输入框
    解决adb网络连接中出现的“由于目标计算机积极拒绝,无法连接”错误
  • 原文地址:https://www.cnblogs.com/strive-man/p/8678096.html
Copyright © 2011-2022 走看看