进程的概念:(Process)
进程就是正在运行的程序,它是操作系统中,资源分配的最小单位.
资源分配:分配的是cpu和内存等物理资源
进程号是进程的唯一标识
同一个程序执行两次之后是两个进程
进程和进程之间的关系: 数据彼此隔离,通过socket通信
并行和并发
并发:一个cpu同一时间不停执行多个程序
并行:多个cpu同一时间不停执行多个程序
cpu的进程调度方法
# 先来先服务fcfs(first come first server):先来的先执行
# 短作业优先算法:分配的cpu多,先把短的算完
# 时间片轮转算法:每一个任务就执行一个时间片的时间.然后就执行其他的.
# 多级反馈队列算法
越是时间长的,cpu分配的资源越短,优先级靠后
越是时间短的,cpu分配的资源越多
进程三状态图
[图片上传失败...(image-a9788e-1576307991857)]
(1)就绪(Ready)状态
只剩下CPU需要执行外,其他所有资源都已分配完毕 称为就绪状态。
(2)执行(Running)状态
cpu开始执行该进程时称为执行状态。
(3)阻塞(Blocked)状态
由于等待某个事件发生而无法执行时,便是阻塞状态,cpu执行其他进程.例如,等待I/O完成input、申请缓冲区不能满足等等。
[图片上传失败...(image-f2862a-1576307991857)]
同步 异步 / 阻塞 非阻塞
场景在多任务当中
同步:必须等我这件事干完了,你在干,只有一条主线,就是同步
异步:没等我这件事情干完,你就在干了,有两条主线,就是异步
阻塞:比如代码有了input,就是阻塞,必须要输入一个字符串,否则代码不往下执行
非阻塞:没有任何等待,正常代码往下执行.
# 同步阻塞 :效率低,cpu利用不充分
# 异步阻塞 :比如socketserver,可以同时连接多个,但是彼此都有recv
# 同步非阻塞:没有类似input的代码,从上到下执行.默认的正常情况代码
# 异步非阻塞:效率是最高的,cpu过度充分,过度发热
jion控制异步并发控制
# ### join 等待所有子进程执行完毕之后,主进程再立刻执行
from multiprocessing import Process
import time,os
#基本语法
"""
def func():
print("发送第一封邮件")
if __name__ == "__main__":
p = Process(target=func)
p.start()
time.sleep(0.1)
#join的作用子进程跑完,立刻向下执行,不需要额外的等待多余时间
#p.join()
print("发送第二封邮件")
"""
'''
#多个子进程,进行同步控制
def func(index):
print("发送第%s封邮件"%(index))
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()
print("最后发送完毕之后,抄送给王总的总结邮件")
##使用自定义的方法创建进程
class MyClass(Process):
#方法名字必须是run,同handle是一个道理
def run(self):
print("1当前的子进程{},2父进程是{}".format(os.getpid(),os.getppid()))
if __name__ == "__main__":
p = MyClass()
p.start()
print("3当前的子进程{},父进程是{}".format(os.getpid(),os.getppid()))
'''
#带有参数的自定义进程
class MyProcess(Process):
def __init__(self,arg):
#手动调用父类构造方法__init__
super().__init__() #不能使用self会穿线递归现象
self.arg = arg
#在调用进程是,默认会执行run方法中的代码块
def run(self):
print("当前子进程%s,父进程%s"%(os.getppid(),os.getppid()))
print(self.arg)
if __name__ == "__main__":
lst = []
#循环创建多个子进程
for i in range(10):
p = MyProcess(i)
p.start()
lst.append(p)
for i in lst:
i.join()
print("主进程执行结束")
守护进程
#可以给子进程贴上守护进程的名字,该进程会随着主进程代码执行完毕而结束(为主进程守护)
(1)守护进程会在主进程代码执行结束后就终止
(2)守护进程内无法再开启子进程,否则抛出异常(了解)
# ### 守护进程
"""
默认情况下,主进程等待所有子进程执行完毕之后,关闭程序,释放资源
守护进程是在主进程代码执行结束之后,直接关闭
语法:
进程.daemon = True 设置当前进程为守护进程
守护进程守护的是主进程;如果主进程代码执行结束了,守护进程立刻终止
在定义时,必须写在start()调用之前.
"""
from multiprocessing import Process
import time
# (1) 基本用法
"""
def func():
print("当前子进程start")
print("当前子进程end")
if __name__ == "__main__":
p = Process(target=func)
p.daemon = True
p.start()
print("主进程执行结束... ")
"""
# (2) 多个子进程场景
"""
def func1():
count = 1
while True:
print("*" * count)
time.sleep(0.5)
count += 1
def func2():
print("func2 start ...")
time.sleep(3)
print("func2 end ...")
if __name__ == "__main__":
p1 = Process(target=func1)
p2 = Process(target=func2)
p1.daemon = True
p1.start()
p2.start()
time.sleep(1) # 可以看到打印2~3次,由于主进程执行结束.终止守护进程;
print("主进程代码执行结束 .. ")
"""
# (3)守护进程的实际用途: 监控报活
def alive():
# 实时报活
while True:
print("10号服务器目前运行状态良好... i am ok ~")
time.sleep(0.5)
def func():
# 统计报表
print("当前服务器统计报表中 ... ")
time.sleep(3)
print("报表异常 ... ")
if __name__ == "__main__":
p1 = Process(target = alive)
# 设置监控任务为守护进程
p1.daemon = True
p1.start()
p2 = Process(target = func)
p2.start()
# 如果统计报表这个任务异常了,join不会添加阻塞,守护进程立刻终止,不会发送报活信息;
p2.join()
print("主程序执行结束... ")