进程
进程: 正在进行的一个过程或者说一个任务. 由CPU执行.
并发与并行
多道技术概念:内存中同时存入多道(多个)程序,cpu从一个进程快速切换到另外一个,使每个进程各自运行几十或几百毫秒,这样,虽然在某一个瞬间,一个cpu只能执行一个任务,但在1秒内,cpu却可以运行多个进程,这就给人产生了并行的错觉,即伪并发,以此来区分多处理器操作系统的真正硬件并行(多个cpu共享同一个物理内存)
无论是并发还是并行,在用户看来都是‘同时’运行的, 不管是进程还是线程, 都只是执行一个任务。
- 并发 : 是伪并行,有单个cpu + 躲到技术就可以实现并发(并行也属于并发)
- 并行:同时运行, 只有具备多个cpu才能实现并行
同步/异步和阻塞/非阻塞
- 同步 : 调用一个操作,要等等待结果
- 异步 : 调用一个操作,不等待结果
- 阻塞 : CPU不工作
- 非阻塞 : CPU工作
进程三状态
- 就绪----->运行---->阻塞
(进程调度)
创建---(提交)----> 就绪<----------->运行 ----(释放)---> 退出
\ (时间到) /
事件发生\ /事件请求
\ /
\ /
阻塞
import time
print(‘程序运行‘) # 运行
name = input(‘>>>‘) # 阻塞(在等待用户输入,进入阻塞)
# 用户输入不是立即运行, 进入就绪状态,等待操作系统调度
print(name) # CPU空闲时进入运行
time.sleep(1) # 阻塞, 就绪
print(‘程序结束‘) # 运行 , 结束
进程的调度算法
-
给所有的进程分配资源或者分配CPU使用权的一种方法
-
多级反馈算法
- 多个任务队列,优先级从高到低, 新来的任务总是优先级最高的
- 每一个新任务几乎会立即获得一个时间片时间
- 执行完一个时间片之后就会降到下一级队列中
- 总是优先级高的任务都执行完才执行优先级低的队列
- 并且优先级越高时间片越短
-
例如: 先来先服务,
multiple模块
开启进程
from multiprocessing import Process
import os
def func(name,age):
print(os.getpid(), os.getppid, name) # getpid 进程id
# getppid 父类进程id
print(‘执行了两次‘) # 子进程再执行了一次
if __name__ == ‘__main‘: # 父进程 , 防止子进程再次调用,陷入循环
print(‘main‘, os.getpid(), os.getppid)
p = Process(target= func,arg = (‘小白‘,12) # 传参
p.start() # 开辟一个进程,操作系统会开辟一个空间并copy父进程内存, 由于‘__name__‘,只执行func()
- 同步阻塞---join 异步非阻塞-----start
开启进程的另一种方法
import os
import time
from multiprocessing import Process
class MyProcess(Process): 继承Process类
def __init__(self,a):
self.a = a
super().__init__()
def run(self):
time.sleep(1)
print(os.getppid(),os.getpid(),self.a)
if __name__ == ‘__main__‘:
print(‘-->‘,os.getpid())
for i in range(10):
p = MyProcess(1) # 创建实例化对象
p.start()
守护进程
-
主进程会等待所有的子进程结束,是为了回收子进程的资源
-
守护进程会等待主进程的代码执行结束之后再结束,而不是等待整个主进程结束.
-
主进程的代码什么时候结束,守护进程就什么时候结束,和其他子进程的执行进度无关
from multiproessing import Process
def aaa():
time.sleep(1)
print(‘结束‘)
def bbb():
time.sleep(2)
print(‘子进程结束‘)
if __name__ == ‘__main__‘:
p1 = Process(target=aaa)
p1.daemon = True # 表示设置p1是一个守护进程
p1.start()
Process(target = bbb).start() # 子进程
锁(互斥锁)
import time
from multiprocessing import Lock,Process
def func(i,lock):
# lock.acquire() # 拿钥匙
# print(‘被锁起来的代码%s‘%i)
# lock.release() # 还钥匙
with lock: # 自动归还锁,
print(‘被锁起来的代码%s‘%i)
time.sleep(1)
if __name__ == ‘__main__‘:
lock = Lock()
for i in range(10):
p = Process(target=func,args=(i,lock))
p.start()
队列Queue
- 基于socket的文件级别的通信来完成数据传递的
生产者消费者模型
- 本质: 就是让生产数据和消费数据的效率达到平衡并且最大化的效率
import time
from multiprocessing import Queue,Process
def consumer(q): # 消费者:通常取到数据之后还要进行某些操作
for i in range(10):
print(q.get())
def producer(q): # 生产者:通常在放数据之前需要先通过某些代码来获取数据
for i in range(10):
time.sleep(1)
q.put(i)
if __name__ == ‘__main__‘:
q = Queue()
c1 = Process(target=consumer,args=(q)).start()
p1 = Process(target=producer,args=(q)).start()