并发编程
基础概念
并行和并发
- 并行 同一时刻,多个任务在多个cpu中被执行
- 并发 同一时间段内,多个任务交替执行在cpu上
异步和同步- 异步 : 两个任务(当前所在的代码,和另一个独立的任务)之间没有明确的先后关系
一个任务的继续并不影响到另一个任务的执行 - 同步 : 两个任务之间有明确的先后关系
一个任务的继续必须依赖于上一个任务的结果
- 异步 : 两个任务(当前所在的代码,和另一个独立的任务)之间没有明确的先后关系
阻塞和非阻塞
- 阻塞 :等待io操作结束
- 非阻塞 :不等待io操作结束
进程和线程和协程- 进程(multiprocess) 操作系统中资源分配的最小单位,最大特点:资源独立;能利用多核;有数据安全问题: 同时操作数据库,操作文件占用操作系统资源开销大
- 线程(threading)操作系统中cpu调度的最小单位,资源共享;能利用多核;有数据安全问题:同时处理内存就会出现问题占用的操作系统资源相对,最大特点 处理并发
- 协程(gevent) 操作系统不可见,资源共享,不能利用多核,本质是一条线程,没有数据安全问题:无占用的操作系统资源相当于一条线程
- 进程和程序 :运行中的程序是一个进程
进程的三状态 :就绪 运行 阻塞
GIL锁 CPython解释器中管理线程的机制 保证了CPython解释器中
多个线程 只有一个线程在同一时间点能访问cpu
由于CPython解释器导致了我们不能充分利用多线程来访问多个CPU
-
多进程 : 帮助我们在Cpython解释器下利用多核
-
多线程 : 当我们不确定io操作或者python语言没有给这个io操作设置协程识别的语法的时候就需要使用线程了
-
协程 : 在单线程中,有n个任务,这n个任务如果同步执行,那么所有的io时间是累加在一起的, 协程永远不会数据不安全 因为协程是由程序员控制的,而程序员控制的只能是代码,而不是CPU指令
协程的原理完成一个任务,遇到io之后,能够切换到另一个任务执行,所有的io操作的时间还能做其他任务的执行\这样就可以通过一条线程完成多个任务,协程的本质:就是一条线程 底层切换也是有开销的,切换的开销就和函数调用的开销是一样的
如果是 += *= /= -= 都存在数据不安全的问题 l[0] += 1
如果是 append extend pop remove不会存在数据不安全的问题
#进程代码
from multiprocessing import Process
def target_func(a1,a2,a3): #必须是元组
pass # 计算密集型的代码,高计算代码
p = Process(target=target_func,args=(1,2,3))
p.daemon = True # 守护进程 守护到主进程代码结束(是谁随着主进程代码结束,并不是随着主进程的结束而结束,因为守护进程也是主进程的一个子进程,守护进程的资源需要主进程来回收),和子进程无关,并且一定要在start之前
p.start()#开启一个进程
p.join()#等待进程任务
#进程的流程
#主进程的代码结束
#阻塞
#等待其他非守护进程结束
#子进程全部结束
#回收子进程的资源
#主进程结束