并发编程
2019-06-25 16:29:21 0 举报
AI智能生成
并发编程
作者其他创作
大纲/内容
并发编程
操作系统的发展史
人机矛盾:CPU利用率低
磁带存储 + 批处理
降低数据的存储时间
提高CPU的利用率
多道操作系统
数据隔离
时空复用
能够在一个任务遇到IO操作的时候主动把CPU让出来,给其他任务使用(切换需要占用时间,切换这个事情是操作系统做的)
分时操作系统
给时间分片,让多个任务轮流使用CPU
短作业优先算法
先来先服务算发
时间分片
CPU的轮转
每个程序分配一个时间片
该方法需要切换,要占用时间,反而降低了CPU的利用率,但是提高了用户的体验
分是操作系统 + 多道操作系统 + 实时操作系统
多程序一起在计算机中执行
一个程序如果没有遇到IO操作,但是时间片到了,切出去让出CPU
网络操作系统
分布式操作系统
并行与并发
并行:两个程序两个CPU,每个程序分别占用一个CPU,自己执行自己的(看起来是在同时执行,实际在每一个时间点上,都在各自执行)
并发:两个程序,一个CPU,每个程序交替的在一个CPU上执行(看起来是在同时执行,实际上是串行)
同步和异步
同步:有两个任务,任务一在执行的过程中遇到了任务二时,就会先去执行任务二,执行完任务二才会回来继续执行任务一
异步:有两个任务,他们个执行自己的,互不干扰
阻塞相关
阻塞:CPU不工作
非阻塞:CPU工作
同步阻塞:
同步非阻塞
异步阻塞
异步非阻塞
进程
定义:运行中的程序
程序和进程之间的关系
程序只是一个文件
进程是这个文件被CPU运行起来了
进程是计算机中最小的资源分配单位
操作系统调度进程的算法
短作业优先
先来先服务
时间片轮转
多级反馈算法
进程的三状态图
子主题
进程的特点
开销大
利用多核
进程之间共享数据的安全问题
lock
同时执行好几段代码
进程模块process
from multiprocessing import Process
start
terminate
is_alive
join方法:阻塞直到子进程结束就结束阻塞
daemon:守护进程
使用面向对象的方式
操作系统创建进程的方式不同
Windows
实际上新的子进程需要通过import父进程的代码来完成数据的导入工作,相当于在子进程中把主进程文件又从头到尾执行了一遍
所以有一些内容我们只希望在父进程中完成,就写在if __name__ == '__main__':下面
iOS/Linux
不执行代码,直接执行调用的func函数
主进程和进程之间的关系
主进程的结束逻辑
主进程的代码结束
所有子进程的代码结束
给子进程回收资源
主进程结束
如果子进程执行结束,主进程没有回收子进程资源,子进程就变成了僵尸进程
主进程是如何知道子进程结束了的?
基于网络、基于文件
锁
进程之间的通信
IPC
Queue
Pipe
生产者消费者模型
把一个产生数据并且处理数据的过程解耦,让生产数据的过程和处理数据的过程达到一个工作效率上的平衡
进程之间的数据共享
manager类
线程
定义:是进程当中的一部分,每一个进程中至少有一个线程,线程是负责执行具体的代码的
线程是能被CPU 调度的最小的单位
开销:线程的创建也需要一些开销,他的创建、销毁、切换远小于进程
线程的特点
数据共享
开销小
是进程的一部分
不能独立存在
本身可以利用多核
cpython解释器不能实现多线程利用多核
垃圾回收机制
引用计数
分代回收
锁:GIL 全局解释器锁
保证了整个Python程序中,只能有一个线程被CPU执行
原因:cpython解释器中特殊的垃圾回收机制
GIL锁导致了程序不能并行,可以并发,所以使用线程并不影响高IO型的操作,只会对高计算型的程序有效率上的影响
线程模块
from threading import Thread
join
面向对象的方式
其他的方法:enumerate、active_count、current_thread、ident
守护线程:守护线程一直等到所有的非守护线程都结束之后才结束,除了守护了主线程的代码之外还会守护子线程
互斥锁:不能连续acquire多次
递归锁:可以连续多次acquire
完整的单例模式
线程队列
Queue:先进先出
LifoQueue:后进先出
PriorityQueue:优先级队列
池
进程池:ProcessPool
from concurrent.futures import ProcessPoolExecutor
submit:提交任务
shutdown:关闭池之后就不能继续提交任务,并且会阻塞,直到已经提交的任务完成
result:返回值
线程池:ThreadPool
from concurrent.futures import ThreadPoolExecutor
回调函数
规律的总结
协程
定义:能够在一个线程下的多个任务之间来回切换,那么每一个任务都是一个协程
协程是操作系统不可见的
在cpython解释器下,协程和线程都不能利用多核,都是在一个CPU上轮流执行
由于多线程本身不能利用多核,所以即便是开启了多个线程也只能轮流在一个CPU上执行
协程如果把所有的IO操作都规避掉,只剩下需要用CPU的操作,就意味着协程可以做到提高CPU利用率的效果
多线程和协程
切换需要操作系统,开销大,操作系统不可控,给操作系统的压力大
切换需要Python代码,开销小,用户操作可控,完全不会增加操作系统的压力
切换问题
原生Python完成 yield asyncio
C语言完成的Python模块
协程模块
greenlet
gevent
asyncio
0 条评论
回复 删除
下一页