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