并发编程
操作系统发展史
穿孔卡片>>>联机批处理系统>>>脱机批处理系统
(cpu利用率的发展史)
多道技术
单道按序排队效率低,多道一心多用,合理安排效率高
切换 cpu进入IO操作或长时间占用会切换程序执行
保存状态 切换前记录当前执行状态,切换后依此状态执行
进程
进程理论
先来先服务算法>>>短作业优先>>>时间片轮转法+多级反馈队列
均分时间,优先降低
并行与并发
- 多个进程同时执行称为并行(多核实现,属于并发)
- 多个进程看起来像同时执行称为并发(多单核无所谓)
三种状态
阻塞态与非阻塞态(就绪态,运行态)

同步与异步
- 提交任务等待,得到结果的行为称为同步
- 提交任务后自动提醒结果的行为称为异步
同步阻塞
同步非阻塞
异步阻塞
异步非阻塞
1.鼠标双击
2.代码创建(两种方式)
需要的模块 from multiprocessing import Process
相关方法
1.直接在代码中添加time.sleep (不合理) X
2.join方法 (合理) √
多个进程数据之间彼此默认互相隔离,交互需要借助管道或者队列
守护进程
僵尸进程,孤儿进程
1.进程运行结束,相关的资源未完全清空,需要父进程参与回收的叫做僵尸进程
2.父进程意外死亡,子进程正常运行,子进程就称之为孤儿进程。操作系统会自动分配进程接收孤儿进程
- 互斥锁将并发变为串行(效率变低,安全性变高)
- 互斥锁只出现在多个程序操作数据的地方
线程
线程理论
相关方法
线程对象相关的方法
active_count()
- 进程下的所有的非守护线程结束,主进程才能真正的结束
GIL解释
-
- GIL的研究是Cpython解释器的特点 不是python语言的特点
-
- GIL本质也是一把互斥锁
-
- GIL的存在使得同一个进程下的多个线程无法同时执行(关键)
-
- GIL的存在主要是因为cpython解释器中垃圾回收机制不是线程安全的
python的多线程确实无法使用多核优势 但是在IO密集型的任务下是有用的
GIL只确保解释器层面数据不会错乱(垃圾回收机制)
针对程序中自己的数据应该自己加锁处理
所有的解释型编程语言都没办法做到同一个进程下多个线程同时执行
验证GIL
并发流程:
一百个进程抢一把锁,抢到之后执行进程操作,全局中的num每抢一次就自减一, 当前进程运行完毕。其他进程又进行此操作,随后重复该操作
特点
流程:
一百个进程抢一把锁,抢到之后执行进程操作,全局中的num每抢一次先进行 IO操作,放出抢到的锁,其他进程又可以进行抢锁。每个程序睡眠结束后自减1, 没有锁,所以每次不会继承上一次的进程的num,得到的数仍为num-1之后的数。
python多线程
1. 单个cpu的IO密集型 多线程优势大
2. 单个cpu的计算密集型 多线程优势大
3. 多个cpu的IO密集型 多线程优势大
4. 多个cpu的计算密集型 多进程优势大
死锁现象
信号量
- 信号量本质上是多把互斥锁
- Lock产生的是一把锁,信号量产生的是多把锁
在并发编程中 信号量就是多把互斥锁
在django中 信号量指的是达到某个条件自动触发(中间件)
event事件
进程池与线程池
- 考虑到硬件的承受能力,为了保证计算机硬件的安全,所以需要进程池和线程池
- 进程池或线程池会提前创建好固定个数的进程供程序使用,后续不会再创建
- 使用
协程
- 协程是程序员自己定义出出来的一种方法,可以在单线程下实现并发,效率极高
- 实质是隐瞒IO操作,核心是自己写代码完成切换+保存状态
- 使用