0. 扫盲
1. 多道技术
单核实现并发的效果
2. 并行/并发术语解释
2.1 并发
- 看起来像同时运行的就可以称之为并发
2.2 并行
- 真正意义上的同时执行
2.3 并行与并发的关系
- 并行肯定算并发
- 单核的计算机肯定不能实现并行,但是可以实现并发!!!
2.4 多道技术图解
- 节省多个程序运行的总耗时
2.5 多道技术重点知识
空间上的复用与时间上的服用
-
空间上的复用
多个程序公用一套计算机硬件
-
时间上的复用
例子:洗衣服30s,做饭50s,烧水30s
单道需要110s,多道只需要任务做长的那一个 切换节省时间
例子:边吃饭边玩游戏 保存状态
-
切换+保存状态
2.6 程序与进程的区别
- 程序就是一堆躺在硬盘上的代码,是“死”的
- 进程则表示程序正在执行的过程,是“活”的
2.7 进程调度
先来先服务调度算法
- 对长作业有利,对短作业无益
短作业优先调度算法
- 对短作业有利,多长作业无益
2.8 两对重要概念
同步和异步
- 描述的是任务的提交方式
- 同步:
任务提交之后,原地等待任务的返回结果,等待的过程中不做任何事(干等),
程序层面上表现出来的感觉就是卡住了
- 异步:
任务提交之后,不原地等待任务的返回结果,直接去做其他事情。
我提交的任务结果如何获取?
任务的返回结果会有一个异步回调机制自动处理。
2.9 阻塞非阻塞
- 描述的程序的运行状态
- 阻塞:阻塞态
- 非阻塞:就绪态、运行态
- 理想状态:我们应该让我们的写的代码永远处于就绪态和运行态之间切换
- 上述概念的组合:最高效的一种组合就是异步非阻塞
3. 开启进程的两种方式
3.1 创建的方式:(一般用第一种)
from multiprocessing import Process
import time
def task(name):
print('%s is running'%name)
time.sleep(3)
print('%s is over'%name)
if __name__ == '__main__':
# 1 创建一个对象
p = Process(target=task, args=('jason',)) # 第一个参数:函数名称,第二个:传递的参数
# 容器类型哪怕里面只有1个元素 建议要用逗号隔开
# 2 开启进程
p.start() # 进程创建完成,等待cpu调度,调度时间,未定
print('主')
# 第二种方式 类的继承
from multiprocessing import Process
import time
class MyProcess(Process):
def run(self):
print('hello bf girl')
time.sleep(1)
print('get out!')
if __name__ == '__main__':
p = MyProcess()
p.start()
print('主')
3.2 创建进程的总结
- 创建进程就是在内存中申请一块内存空间将需要运行的代码丢进去,
- 一个进程对应在内存中就是一块独立的内存空间,
- 多个进程对应在内存中就是多块独立的内存空间。
- 进程与进程之间数据默认情况下是无法直接交互,如果想交互可以借助于第三方工具、模块。
4. 进程常用的方法
4.1 join
- join是让主进程,等待子进程代码,运行结束之后,再继续运行。不影响其他子进程的执行
- 案例
from multiprocessing import Process
import time
def task(name, n):
print('%s is running'%name)
time.sleep(n)
print('%s is over'%name)
if __name__ == '__main__':
# p1 = Process(target=task, args=('jason', 1))
# p2 = Process(target=task, args=('egon', 2))
# p3 = Process(target=task, args=('tank', 3))
# start_time = time.time()
# p1.start()
# p2.start()
# p3.start() # 仅仅是告诉操作系统要创建进程
# # time.sleep(50000000000000000000)
# # p.join() # 主进程等待子进程p运行结束之后再继续往后执行
# p1.join()
# p2.join()
# p3.join()
start_time = time.time()
p_list = []
for i in range(1, 4):
p = Process(target=task, args=('子进程%s'%i, i))
p.start()
p_list.append(p)
for p in p_list:
p.join()
print('主', time.time() - start_time)
4.2 其他方法
"""
一台计算机上面运行着很多进程,那么计算机是如何区分并管理这些进程服务端的呢?
计算机会给每一个运行的进程分配一个PID号
如何查看
windows电脑
进入cmd输入tasklist即可查看
tasklist |findstr PID查看具体的进程
mac电脑
进入终端之后输入ps aux
ps aux|grep PID查看具体的进程
"""
from multiprocessing import Process, current_process
current_process().pid # 查看当前进程的进程号
import os
os.getpid() # 查看当前进程进程号
os.getppid() # 查看当前进程的父进程进程号
p.terminate() # 杀死当前进程
# 是告诉操作系统帮你去杀死当前进程 但是需要一定的时间 而代码的运行速度极快
time.sleep(0.1)
print(p.is_alive()) # 判断当前进程是否存活
5. 进程之间数据隔离
- 进程之间数据不共享
- 线程数据共享