一、上节回顾
开启进程:
from multiprocessing import Process import time def task(name): print("%s is running"%name) time.sleep(2) print("%s is stopping"%name) if __name__=="__main__":#在windows系统下,开启子进程必须写到这一行下面 p=Process(target=task,args=("egon",)) p.start() #只是在给操作系统发了一个信号,让操作系统去开启进程(申请内存+拷贝父进程的地址空间) print("主")
1、什么是进程?
进程是一个抽象的概念,进程即正在执行的过程,进程的概念起源于操作系统,
进程的创建,调度管理都贵操作系统管
2、操作系统的作用?
1、管理的硬件,把复杂丑陋的硬件接口封装成良好的接口给客户使用
2、进程的创建,调度管理都贵操作系统管理
3、多道技术?
产生背景:针对单核下实现并发
核心:
1、空间上复用(多个进程的内存空间是互相隔离的)
2、时间上的复用(复用cpu的时间)
一些小知识:
cpu 时间片是指的cpu中的一小块时间
作业讲解中遇到的问题:
(1)并发是指的任务
(2)实现服务端的并发
(3)服务端的作用:建立连接 通信
(4)开启进程:
(5)listen是指的操作系统的限制,队列是占用的内存的空间
第一次握手是指的操作系统从从队列中取走一个回给客户端
(6)操作系统不仅干TCP建立连接的活,还要做其他的工作
(7)一个server对象产生一个端口建立连接
(8)一个服务端于多个客户端实现并发
(9)进程的开启,是占用内存空间,不可能无限的开启进程,客户端有可能会开启一个上百万的进程
二、新内容
(一、开启进程)
1、进程的两种方式
# # 方式一 from multiprocessing import Process import time def task(name): print("%s is running"%name) time.sleep(2) print("%s is stopping"%name) if __name__=="__main__":#在windows系统下,开启子进程必须写到这一行下面 p=Process(target=task,args=("egon",)) p.start() #只是在给操作系统发了一个信号,让操作系统去开启进程(申请内存+拷贝父进程的地址空间) print("主")
方式二(不重要,不符合规范) from multiprocessing import Process import time class Myprocess(Process): def __init__(self,name): super().__init__() self.name=name def run(self): time.sleep(2) print("%s is running"%self.name) time.sleep(3) if __name__=="__main__": p=Myprocess("egon") p.start() print("主")
2、python解释器相当于一个函数,将写的代码编程能运行的程序
一个程序运行两遍就是两个进程,就相当于一个py关掉又运行了一次(讲特性(线程)的时候会用到)
import time,os print(os.getpid(),os.getpid()) time.sleep(10) #python3 test.py----->python.exe
3、僵尸进程:父进程,结束进程还存在
正常存在是先是子进程结束,然后结束父进程
重要点:start join
确定子进程结束之后才会进行主进程 使用join()
开启进程的方法 p.start() 只是传递信号给操系统,并没有顺序
没有办法实现顺序执行
from multiprocessing import Process import time def task(name): print("%s is running"%name) time.sleep(2) if __name__=="__main__": p1=Process(target=task,args=("egon",)) p2=Process(target=task,args=("alex",)) p3=Process(target=task,args=("yxxx",)) p_1=[p1,p2,p3] for p in p_1: p.start() for p in p_1: p.join() print("主")
4、作为了解
from multiprocessing import Process import time def task(name): print("%s is running"%name) time.sleep(2) if __name__=="__main__": p1=Process(target=task,args=("egon",),name="xxxxx") p1.start() print(p1.name) print(p1.pid) #子进程 ID p1.join() #先子进程后主进程 p1.terminate() #强行终止子进程 print(p1.is_alive()) #判断子进程是否还存在 print("主")
5、参数介绍
1 group参数未使用,值始终为None 2 3 target表示调用对象,即子进程要执行的任务 4 5 args表示调用对象的位置参数元组,args=(1,2,'egon',) 6 7 kwargs表示调用对象的字典,kwargs={'name':'egon','age':18} 8 9 name为子进程的名称
方法介绍:
1 p.start():启动进程,并调用该子进程中的p.run() 2 p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法 3 4 p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁 5 p.is_alive():如果p仍然运行,返回True 6 7 p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程
属性介绍:
1 p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置 2 3 p.name:进程的名称 4 5 p.pid:进程的pid 6 7 p.exitcode:进程在运行时为None、如果为–N,表示被信号N结束(了解即可) 8 9 p.authkey:进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。这个键的用途是为涉及网络连接的底层进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功(了解即可)
(二、进程池)
提交/调用任务的方式有两种:
同步调用:提交/调用一个任务,然后就在原地等着,等到该任务执行完毕拿到结果,再执行下一行代码
异步调用:提交/调用一个任务,不在原地等着,直接执行下一行代码,结果?
1、异步调用
# from multiprocessing import Process,pool from concurrent.futures import ProcessPoolExecutor import time,random,os def piao(name): print("%s is piaoing %s"%(name,os.getpid())) time.sleep(random.randint(1,4)) if __name__=="__main__": p=ProcessPoolExecutor(4) for i in range(10): p.submit(piao,"alex %s"%i) #关门+等 #pool.close() #pool.join() p.shutdown(wait=True) print("主",os.getpid())
说明:
同时进行的进程一共有四个,四个同时进行(一共造出四个进程,就是有四个ID)
for循环丢进进程只是发出一个信号
2、同步调取结果:
3、异步调取结果
# from multiprocessing import Process,pool from concurrent.futures import ProcessPoolExecutor import time,random,os def piao(name,n): print("%s is piaoing %s"%(name,os.getpid())) time.sleep(1) return n ** 2 if __name__ == '__main__': p=ProcessPoolExecutor(4) objs=[] start=time.time() for i in range(10): # res=p.submit(piao,'alex %s' %i,i).result() #同步调用 # print(res) obj=p.submit(piao,'alex %s' %i,i) #异步调用 objs.append(obj) for obj in objs: print(obj.result()) stop=time.time() print(stop-start) # 关门+等 # pool.close() # pool.join() p.shutdown(wait=True) print('主',os.getpid())
异步调取结果不影响并发的执行:
4、时间的计算:开启进程也需要花费时间,切换的时间,操作系统创建进程申请拷贝空间的时间
开启进程数量越多花费的时间越短(在机器可承受的范围之内的情况下)
from multiprocessing import Process import time,random,os def piao(name,n): print("%s is piaoing %s"%(name,os.getpid())) time.sleep(1) return n**2 if __name__=="__main__": start=time.time() p_1=[] for i in range(10): p=Process(target=piao,args=("ss",1)) p_1.append(p) p.start() for p in p_1: p.join() stop=time.time() print(stop-start)