Python 多线程 锁,python线程死锁的原因
本文主要介绍python多线程互斥锁和死锁,以及多线程之间的资源竞争。接下来我们以task1()和task2()函数为例,对全局变量num加1,重复1000万次,有一定的参考价值。有需要的可以参考一下。
00-1010 1.多线程之间的资源竞争2。互斥锁1。互斥锁2的例子。再入锁和不再入锁3。僵局
目录
以下面两个函数task1()和task2()为例,在全局变量num上加1,重复1000万次(如果数据太大,执行速度太快,达不到验证效果)。
导入线程
导入时间
数量=0
定义任务1(nums):
全局编号
适用于范围内的I(nums):
数量=1
打印(任务1 -数量=%d %数量)
定义任务2(nums):
全局编号
适用于范围内的I(nums):
数量=1
打印(任务2 -数量=%d %数量)
if __name__==__main__:
nums=10000000
t1=线程。线程(target=task1,args=(nums,)
t2=线程。线程(target=task2,args=(nums,)
t1.start()
t2.start()
#因为主线程不会等待子线程完成执行,所以这里有五秒钟的延迟,以确保最后一次执行。
时间.睡眠(5)
打印( main - num=%d % num )
程序运行结果:
如图,输出结果比较混乱,最终结果既不是1000万也不是2000万。因为多线程存在资源竞争,所以可以理解为各个函数的运行时间是不确定的,相互影响。
比如从初始值0开始,假设t1的线程先执行,执行到1后,此时的num=1还没有存储,然后就停止了。t2开始执行获取num,得到的num等于初始值0,然后执行1并存储。存储后num=1,t2停止t1继续,再次存储num=1。也就是1加了两次,但num还是只等于1。
因为谁来跑t1和t2的分配是完全随机的,所以2000万次加1后,值不到2000万。
为了解决这些问题,可以使用互斥体。
一、多线程间的资源竞争
当一个线程想要改变共享数据时,它应该首先被锁定。此时,资源状态为“锁定”,其他线程无法更改它。只有当线程释放资源并将资源状态更改为“未锁定”时,其他线程才能再次锁定资源。互斥锁保证一次只有一个线程写,从而保证多线程情况下数据的正确性。
二、互斥锁
创建一把锁:
互斥=线程。锁定()
Mutex.acquire() # Lock
Xxxx锁定的内容xxxxx
Mutex.release() #解锁
将互斥体添加到上面的代码中,如下所示,问题就解决了。
导入线程
导入时间
数量=0
定义任务1(nums):
全局编号
mutex.acquire()
适用于范围内的I(nums):
数量=1
mutex.release()
打印(任务1 -数量=%d %数量)
定义任务2(nums):
全局编号
mutex.acquire()
适用于范围内的I(nums):
数量=1
mutex.release()
打印(任务2 -数量=%d %数量)
if __name__==__main__:
nums=10000000
互斥=线程。锁定()
t1=线程。线程(target=task1,args=(nums,)
t2=线程。线程(target=task2,args=(nums,)
t1.start()
t2.start()
#因为主线程不会等待子线程完成执行,所以这里有五秒钟的延迟,以确保最后一次执行。
时间.睡眠(5)
打印( main - num=%d % num )
程序运行结果:
1.互斥锁示例
穿线。Lock()是一个不可重入的锁,也就是说,一次只能添加一个锁,不能超过一个。
穿线。锁定()
如果需要同时添加更多的房子,就需要添加一个不可重入的锁。
创建一把可重入锁:
互斥=线程。RLock()
Mutex.acquire() # Lock
Mutex.acquire() #再次锁定
Xxxx锁定的内容
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。