python之路---并发编程之进程&僵尸进程/孤儿进程/守护进程

僵尸进程

子进程在结束之后,释放掉其占用的绝大部分内存空间以及cpu等资源,但是会留下一个称为僵尸进程的数据结构(包含子进程的pid),等待父进程处理。这种情况下的僵尸进程是无害的(待所有的子进程结束后,父进程会统一向操作系统发送回收子进程pid的请求,或者使用join(),其内部也拥有wait()方法),但是,如果父进程是一个死循环,不断的创造子进程,而又不发送回收请求,这就造成了大量的pid被占用

孤儿进程

在子进程结束之前,父进程就挂掉了,该子进程称之为孤儿进程(无害),最后会由所有进程的父进程进行发送回收请求(linux中为init进程) 

守护进程

两个关键词:守护/进程

进程:其本质也是一种“子进程”

守护:伴随的意思

即,守护进程会伴随着父进程代码的执行结束而死亡(彻彻底底,而非成为僵尸进程)

为什么要用守护进程

当该进程的代码在父进程的代码执行完毕后就没有存在的意义了,则应该将该进程设置为守护进程(例如在生产者与消费者模型中,生产者是专门负责产生数据的任务,而消费者是负责处理数据的任务,当生产者对象join之后,意味生产者不再生产数据,也意味着执行父进程的下一行代码,而消费者处理的数据来自生产者,所以应该将充当消费者的子进程设置为守护进程)

如何将进程设置为守护进程

import time
from multiprocessing import Process


def bar(name):
    print("%s is running" % name)
    time.sleep(3)
    print("%s is done" % name)


def foo(name):
    print("%s is running" % name)
    time.sleep(3)
    print("%s is done" % name)


if __name__ == '__main__':
    p1 = Process(target=bar, args=('守护进程',))
    p2 = Process(target=foo, args=('子进程',))
    p1.daemon = True  # 开启守护进程一定要在父进程发送请求之前
    p1.start()
    p2.start()
    print('主is done')

在这种情况下,执行结果可能有三种(取决于计算机的性能)

分析之前,首先要明确的是

1.start()操作只是代表父进程向操作系统发送创建子进程的请求(而非立即产生子进程),至于什么创建,先创建谁由操作系统决定

2.产生进程是需要开辟内存空间的,为子进程分配pid,通过导入的方式将父进程的代码复制到子进程中(还有其它资源),这些都是需要一定的时间

3.守护进程是伴随着父进程的代码执行完毕而结束(而非父进程的死亡)

4.print()操作,是先在内存中产生字符串这个对象,然后将其输出到屏幕上,这也是需要一定的时间

结果一

主进程is done
子进程 is running
子进程 is done

这是由于执行两个start()之后,立即执行了print()操作,待父进程代码执行完毕后,守护进程仍然没有被创造出来

结果二

主进程is done
守护进程 is running
子进程 is running
子进程 is done

这是由于,在父进程执行print()操作的时候,守护进程被创建出来

结果三

守护进程 is running
主进程is done
子进程 is running
子进程 is done

这是由于在父进程向操作系统发送申请子进程的时候,守护进程被创建出来

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值