线程
在python当中线程调用了threading
模块对thread
做了包装。方便使用。
多线程相比较单线程花费的时间短,多线程使用了并发的操作,在调用start()时,才会真正的创建线程,开始执行。
在进程内的所有线程共享全局变量,很方便在多个线程间共享数据。
但是多个线程同时对同一个全局变量操作,会出现资源竞争问题,导致数据结果可能会不正确。
互斥锁
线程在保证同步安全访问竞争资源,可以引入互斥锁。
在某个线程想要更改共享数据时,先将其锁定,其他线程将不得修改,知道线程释放资源后,其他线程才能再次锁定资源。互斥锁就是保证每次只有一个线程进行操作。保证了多线程的数据正确性。
Lock类,可以方便处理锁定
#创建锁
mutex = threading.lock()
#锁定
mutex.acquire()
#释放
mutex.release()
死锁
在线程间共享多个资源的时候,如果俩个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。
进程
进程是操作系统分配资源的基本单元
进程一般通过multiprocessing
模块创建对象。
进程一般至少有一个线程,并且线程不能独立执行,必须依存在进程中。线程的开销相对小,但不利于资源的保护和管理。进程相反。
协程
迭代器
迭代是访问集合元素的一种方式,迭代器是一个可以记住遍历的位置的对象,迭代器对象从集合的第一个元素开始访问,知道所有集合元素被访问完结束。迭代器只能往前不能往后。
迭代器最核心的功能就是通过next()函数来调用返回下一个数据值。
用迭代器写一个斐波那锲数列
class Feibona():
def __init__(self,n):
self.n = n
self.index = 0
self.num1 = 0
self.num2 = 1
def __next__(self):
if self.index < self.n:
num = self.num1
self.num1,self.num2 = self.num2,self.num1+self.num2
self.index +=1
return num
else:
raise StopIteration
def __iter__(self):
return self
if __name__ == '__main__':
fb = Feibona(20)
for i in fb:
print(i,end=',')
结果为:
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,
生成器
生成器是特殊的迭代器
只要def中有yield关键字就是生成器
yield关键字有两点作用:
- 保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起
- 将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用
协程是另一种实现多任务的方式,只不过比线程更小的占用更小的执行单元。
协程的切换只是单纯的操作CPU的上下文,所以切换次数很多次也不怕。
进程,线程,协程区别
- 进程是资源分配的单位
- 线程是操作系统调度的单位
- 进程切换需要的资源最大,效率低
- 线程切换需要资源一般,效率一般
- 协程切换资源很小,效率高
- 多进程,多线程根据cpu核数不一样可能是并行,但是协程是在一个线程中,所以是并发