线程
应用:
IO操作密集型程序
进程的最小组成单位,也是唯一的组成单位
把进程分成时间片的方式,通过抢占时间片的方式来执行
特性:
一个进程至少包含一个线程(主线程)
组成:线程ID,指令指针,寄存器,堆栈
是进程执行的最小单位
线程之间相互独立,但资源共享(进程的资源)
线程间的调度和切换比进程要快的多
特点:
宏观并行,微观串行
分类:
单线程和多线程
多线程
模块:
threading
类:
Thread
方式:
一:
继承线程类,并重写run()方法
class A(threading.Thread):
def __init__(self):
super().__init__(self)
def run(self):
pass
t=A()
t.start()
二:
直接创建
def fun(name):
print(name)
if __name__=='__main__':
t=threading.Thread(group=None,target=None,args=(),kwargs=None,name=None,daemon=None)
group 创建的组
target 传入的函数名
args target传入函数的参数
kwargs 关键字参数
name 线程名字
daemon 守护进程
方法:
getName() 获得线程名
setName() 设置线程名
ident 获得线程id
id_alive() 线程是否活着
join([time]) 阻塞调用这个方法线程 time阻塞的秒数
setDaemon() 设置守护线程
start() 启动线程
isDaemon() 是否是守护线程
线程状态:
新建状态->就绪状态->运行状态->阻塞状态(join)->死亡状态(执行结束)
多线程的作用:
应用于计算密集型程序
多个线程同时对资源读取的时候,可能造成数据脏读的问题
全局锁
GIL global interpreter lock 全局锁
应用于计算密集型程序作用:解决线程同步(多线程并发执行,可能会对数据造成脏读)
为了解决多线程 安全问题,容易造成数据脏读等问题
影响:
使多线程几乎等同于单线程
简介:
就是只有全局锁的线程才能运行,直到运行的时间片结束,抛出全局锁,但是这样会让,该线程下次继续获得该锁
原理:其他线程都处于就绪状态,而该线程处于运行状态
释放全局锁:
线程运行超过15ms
程序运行大小超过1000个字节
当IO阻塞时,由于GIL锁的问题,会让其他线程继续运行
IO对CPU的使用少,所以几乎用不到
使用:
模块:threading
类:lock()
应用:
对容易出现数据脏读的程序
方法:
加锁 acquire()
解锁 release()
死锁问题:
当对程序加锁的时候,多次加锁,会造成死锁问题
解决:
RLock()
方法:
同锁,就类不一样,方法都一样
进程
作用:
是系统分配资源的最小单位
特性:
动态性
动态执行
并发性
宏观并行
独立性
个个进程相互独立,互不影响
结构性
拥有特定的结构
组成:
程序:用户描述进程要完成的功能,是控制进程执行的指令集
数据集合:是程序在执行的时候说需要的数据和工作区
进程控制块:包含进程的描述信息和控制信息,是进程存在的唯一标识
分类:
单进程和多进程
多进程
解决:
多线程的限制
引用:
计算密集型的程序(CPU密集型程序,cpu是用于计算的
模块:
multiprocessing
类:
Process() 参数与线程一样
模块包含:
Lock() 进程锁
Pool() 进程池
Queue() 对列,实现进程之间的通信,单向
Pipe() 管道,可以实现进程之间的双向通信
RLock() 解决进程之间的死锁问题
注意应用进程锁的时候,需要把进程锁的对象当做创建进程函数的参数传递
进程池Pool
应用:
创建多个进程的时候,单个创建太麻烦,所以创建进程池
方法:
apply() 阻塞的执行池中的进程
apply_async(self,func,args=(),kwargs=None) 异步的执行池中的过程,就是可以同时执行
close() 关闭进程池
terminate() 关闭进程池
join() 阻塞
创建:
Pool([maxsize]) 可以指定进程池的数量,如果不指定,系统默认为一个
理解:
进程池,当进程池满的时候。外边的进程会等待,直到进程池里面有空余位置,在进入进程池中执行
进程池中进程的执行必须:
close()
join()
或
terminate()
join()
对列Queue
作用:
进程之间的相互通信,先进先出
堆栈:先进后出
模块:multiprocessing
类:Queue(maxsize=0)
实现进程之间的数据交换(进程之间内存不共享)
方法:
put(blocked=True,timeout=None) 发送数据
blocked 设置是否等待,就是当队列满的时候,进程是否等待,timeout为等待的时间。当
timeout大于零的时候,超过时间还没有数据的时候,会报Queue.Full异常
get(blocked=True,timeout=None) 获取数据
同上,当没有数据的时候,是否等待,超时就报Queue.Empty,当为False,直接抛出
get_nowait() 相当于get(False)
put_nowait() 相当于put(False)
empty() 是否为空
full() 是否满了
qsize() 获取队列的个数
管道Pipe
作用:
同上
模块:
multiprocessing
类:
Pipe(dumplex=True) 当为True时,表示全双工,就是两端都可以发收信息
创建:
p=multiprocessing.Pipe(dumplex=Fasle)
得到一个元组con1,con2(con1用于接收数据recv)(con2用于发送数据send)
当管道关闭时,会报EOFError
线程的队列
模块:
queue
类:
Queue()
作用:
线程之间的通信
应用:
消费者与生产者
使用:
同进程队列
线程绑定
在线程使用的时候都是使用系统的变量,为了让线程都拥有自己的变量,就有了线程绑定。
模块:
threading
类:
Local()
使用:
import threading
l=threading.Local()
def fun(value):
l.value=value
使用map实现多线程
模块:
multiprocessing.dummy
类:
Pool()
方法:
map(fun,*iterable)
协程
生成器判断
模块:
inspect
函数:
isgenerator()
isgeneratorfunction()
方法:
async , await实现协程
async 后面定义的函数为协程函数
await 用来声明程序的挂起,当执行await时,先执行await后面的函数
例子:
async func():
print()
await fun2()
print()
async fun2():
pritnt(0)
分析:
当执行到await时,先执行fun2