一、多道技术
1.空间上的复用
多个程序共用一套计算机硬件
2.时间上的复用
切换+保存状态
1).当一个程序遇到IO操作 操作系统会剥夺该程序的cpu执行权限(提高了cpu的利用率 并且也不影响程序的执行效率)
2).当一个程序长时间占用cpu 操作系统也会剥夺该程序的cpu执行权限(降低了程序的执行效率)
time.sleep()本质和时间复用一样 睡觉时候操作系统会切换cpu。
二、进程
1.进程的三状态图
2.串行、并发与并行
串行:程序运行完才能进入下一个程序
并发:只是看起来多个任务在同时执行。单核也可以实现并发
并行:真正意义上的同时运行。可以指资源有限的情况下,两者交替轮流使用资源。只有多核才能实现。
3.同步异步阻塞非阻塞
1)、同步异步:表示的是任务的提交方式
同步:任务提交之后 原地等待的任务的执行并拿到返回结果才走 期间不做任何事(程序层面的表现就是卡住了)
异步:任务提交之后 不再原地等待 而是继续执行下一行代码(结果是要的 但是是用过其他方式获取)
2)、阻塞非阻塞:表示的程序的运行状态
阻塞:阻塞态
非阻塞:就绪态 运行态
三、创建进程
1.什么是进程?
进程指的就是一个正在运行的程序,或者说是程序的运行过程,即进程是一个抽象的概念
为何要进程? 实现并发。
创建进程就是在内存中重新开辟一块内存空间,将允许产生的代码丢进去。一个进程所对应的内存就是一块独立的内存空间。
进程与进程之间数据是隔离的,无法直接交互。但是可以通过某些技术实现间接交互。
同一个程序执行两次,也算是开启了两个进程。
2.创建进程的两种方式
os.cpu_count() 查看电脑是几个处理器。
multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似。
进程间没有任何共享状态,进程修改的数据,改动仅限于该进程内。
创建进程的第一种方式
from multiprocessing import Process import time def test(name): print('%s is running'%name) time.sleep(2) print('%s is over'%name) if __name__ == '__main__': p = Process(target=test,args=('li',))# 创建一个进程对象。当容器类型(此处是元组)中只有一个参数时,最好把逗号加上。
# 第一个传函数的名字过来,第二个传函数要用到的参数。
p.start()# 告诉操作系统帮你创建一个进程 异步 print('主') #注意:windows创建进程会将代码以模块的方式,从上往下执行一遍 # linux会直接将代码完完整整的拷贝一份 # windows创建进程一定要在if __name__ == '__main__':代码块内创建 ,否则会报错
创建进程的第二种方式 from multiprocessing import Process import time class MyProcess(Process): def __init__(self,name): super().__init__() self.name = name def run(self): print('%s is running' % self.name) time.sleep(3) print('%s is over' % self.name) if __name__ == '__main__': p = MyProcess('egon') p.start() #仅仅是告诉操作系统帮你创建一个进程,至于这个进程什么时候创,完全由操作系统随机决定。 print('主')
四、程序中的相关进程用法
1.multiprocess不是一个模块,而是python的一个操作,管理进程的包。
2.process模块介绍及常用语句
from multiprocessing import process 从多道处理中导入过程
Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)
强调:
1). 需要使用关键字的方式来指定参数
2). args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号
3.参数介绍:
1 ).group参数未使用,值始终为None
2) .target表示调用对象,即子进程要执行的任务
3 ).args表示调用对象的位置参数元组,args=(1,2,'egon',)
4). kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}
5). name为子进程的名称
4.常用方法介绍
1)p.start():启动进程,并调用该子进程中的p.run()
2) p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法。
3) p.terminate():强制终止进程p,不会进行任何清理操作。
4 )p.is_alive():判断p是否还活着。如果p仍然运行,返回True
5) p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。
5.join方法
利用p.start()创建多个进程,无法准确获取到进程创建的先后顺序。仅仅是告诉操作系统帮你创建一个进程,至于这个进程什么时候创,完全由操作系统随机决定。
6.守护进程
会随着主程序的结束而结束。
p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程
主进程创建守护进程
1)守护进程会在主进程代码执行结束后就终止
2)守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children
注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止。