day32:进程&进程join&守护进程deamon
目录1.进程的基本概念 2.进程初体验 3.join:先子后主 4.守护进程:deamon 5.使用自定义类的方式创建进程 6.两张和进程相关的图 进程的基本概念什么是进程?进程就是正在运行的程序,它是操作系统中,资源分配的最小单位 什么是资源分配? 资源分配:分配的是cpu和内存等物理资源 Linux中几个关于进程的指令ps -aux? ? 查看进程号 ps -aux | grep 2860? ?查看对应进程号的进程 kill -9 2860? ?杀死进程 pid和ppid获取当前进程id:?os.getpid() 获取当前进程的父进程id:?os.getppid() 并行和并发并发:一个cpu同一时间不停执行多个程序 并行:多个cpu同一时间不停执行多个程序 CPU的进程调度算法1.先来先服务fcfs(first come first server):先来的先执行 2.短作业优先算法:分配的cpu多,先把短的算完 3.时间片轮转算法:每一个任务就执行一个时间片的时间.然后就执行其他的 4.多级反馈队列算法 越是时间长的,cpu分配的资源越少,优先级靠后 越是时间短的,cpu分配的资源越多 进程初体验1.进程的基本使用在使用进程之前,需要调用Process:?from multiprocessing import Process # (1) 进程的基本使用 def func(): print("1.子进程id>>{},2父进程id>>{}".format(os.getpid(),os.getppid())) 为了解决windows 和 linux 系统的兼容问题,下面这句话必须加上,否则报错 if __name__ == __main__: 创建子进程,返回进程对象,执行func这个任务 p = Process(target=func) 调用子进程 p.start() 2.创建带有参数的进程func(n): for i in range(1,n+1): : n = 5 创建子进程 p = Process(target=func,args=(n,)) 调用子进程 p.start() *" * i) 执行结果如下图所示 产生如上结果的原因:因为子进程分配资源需要时间,而主进程早已经分配好资源了,不需要这个时间。所以主进程的内容先打印,子进程的内容后打印 3.进程之间的数据彼此隔离count = 10 global count count += 1 我是子进程count={}.format(count)) : p=Process(target=func) p.start() time.sleep(1) print(count) 执行结果如下图所示 产生如上结果的原因:如下图所示,黄色部分都是子进程中的内容,子进程中有+1操作,所以子进程中的count肯定为11 但是主进程并没有任何操作,只是单纯的打印了一下count,所以主进程中的count为10 4.多个进程之间是异步并发关于主进程和子进程,你需要注意的点: 1.多个进程之间是异步并发的程序,因为cpu的调度策略问题,不一定哪个任务先执行,哪个任务后执行. 整体而言,1)">主进程比子进程创建的速度要快,cpu遇到阻塞会立刻切换任务,等到阻塞态的任务变成了就绪态,cpu再回来执行 2.主程序会默认等到所有的子程序执行结束之后,在统一关闭程序,释放资源. 若不等待,有可能在后台存有多个未执行结束的子进程,会变成僵尸进程,不停的占用cpu,内存 增加系统的压力,所有方便于对进程的管理,1)">主进程默认等待子进程. func(n): time.sleep(random.randrange(3)) 数字{}<=>1.子进程id>>{},1)">.format(n,os.getpid(),11): Process(target=func,1)">(i,)).start() 主进程执行结束了....print(os.getpid()) 执行结果如下图所示 join:先子后主1.join基本语法发送第一封邮箱,要求涨工资) : p = Process(target=func) p.start() 必须等待子进程全部执行结束之后,在执行主进程中的代码,用join来同步子父进程. p.join() time.sleep(1) 发送第二封邮箱,涨到一个月6万") 执行结果如下图所示 2.join:多个子进程func(i): time.sleep(1发送第%s封邮箱,要求升职加薪" % (i)) : lst = [] in range(10): p = Process(target=func,)) p.start() lst.append(p) 把创建的十个子进程对象方放到列表中,现在他们处于就绪态 in lst: i.join() 十个子进程对象同时join 主进程发最后一封邮件:此致敬礼~") 执行结果如下图所示 请注意!!!千万不要写成如下写法: 守护进程deamon1.守护进程的基本概念?概念: 守护进程守护的是主进程,如果主进程中的所有代码执行完毕了, 当前这个守护进程会被立刻杀死,立刻终止. 语法: 进程.daemon = True---->设置当前这个进程为守护进程 必须写在start()调用进程之前进行设置 2.守护进程的基本使用方法start当前子进程) time.sleep(1end当前子进程func) p.daemon = True p.start() 主进程执行结束 ... ") 执行结果如下图所示 3.守护进程:多个子进程func1(): count = 1 while True: " * count) time.sleep(0.5) count += 1 func2(): start func2 当前子进程任务) time.sleep(3end func2 当前子进程任务: p1 = Process(target=func1) p2 = Process(target=func2) 设置p1这个进程对象为守护进程 p1.daemon = True p1.start() p2.start() time.sleep(1) ") 执行结果如下图所示 4.守护进程实际用途:监控报活守护进行 alive(): 给监控的总服务器发消息,报告自己的存活状态,i am alive~) time.sleep(1 执行任务 try: time.sleep(1) raise RuntimeError 当前5号服务器功能:对日志进行数据分析.... ) except: break pass 创建2个子进程 p1 = Process(target=alive) p2 = Process(target= 设置p1为守护进程 p1.daemon = True p1.start() p2.start() 必须等到p2任务执行结束之后,在向下执行. p2.join() 当前服务器状态异常 ... ") 在一切都很正常的时候,它的运行结果是这样的 当出现问题时,它的运行结果是这样的 使用自定义类的方法创建进程?自定义进程类的要求自定义进程类的要求: (1) 必须继承Process这个父类 (2) 所有进程执行任务的逻辑必须写在run方法里面 基本语法class MyProcess(Process): run(self): : p = MyProcess() p.start() 3.子进程id>>{},4父进程id>>{}".format(os.getpid(),os.getppid())) 带有参数自定义类的方法def __init__(self,arg): 手动调用一下父类的构造方法(最终实现进程的创建) super().() self.arg = arg print(self.arg) : p = MyProcess(我是传进来的参数) p.start() |