python线程死锁的原因及解决方法,python多线程锁

  python线程死锁的原因及解决方法,python多线程锁

  大家好,本文主要讲python多线程互斥和死锁的详细讲解。有兴趣的同学过来看看,如果对你有帮助记得收藏。

  00-1010 I .多线程共享全局变量II。给线程III添加一个锁。死锁问题概述

  

目录

  代码实现的功能:

  创建work01和worker02函数,全局变量加一,创建main函数,生成两个线程,同时调用两个函数。

  代码如下:

  导入线程

  Result=0 #定义全局变量结果

  定义工作1(编号):

  全局结果

  对于范围(编号):内的I

  结果=1

  打印(-从工作1 -,结果)

  定义工作2(编号):

  全局结果

  对于范围(编号):内的I

  结果=1

  打印(-从工作2 -,结果)

  定义主():

  打印(- begin -,结果)

  #创建两个线程

  t1=线程。线程(target=work1,args=(1000,))

  t2=线程。线程(target=work1,args=(1000,))

  t1.start()

  t2.start()

  if __name__==__main__:

  主()

  运行结果:

  -开始- 0

  -从工作1到1000

  -来自工作1 - 2000

  全局变量结果在两个线程之间共享,但是当我们增加range的值时,

  t1=线程。线程(target=work1,args=(1000000,))

  t2=线程。线程(target=work1,args=(1000000,))

  我们再来看看结果。这是为什么呢?让我们来看看结果:

  -开始- 0

  -从工作1 - 1358452

  -从工作1 - 1696352

  总结:进程中的所有线程共享全局变量,因此在多个线程之间共享数据非常方便。

  缺点是线程任意修改全局变量,可能会导致多个线程之间的全局变量混淆(即线程不安全)。

  

一、多线程共享全局变量

  如果g_num当前值为100,线程1执行第一步时,cpu通过计算得到结果101,准备将计算结果101赋给g_num,然后在传递值的过程中,线程2突然开始执行,执行第一步。此时g_num的值仍不是100,101仍在转移过程中,赋值不成功。线程2获得计算结果101。准备传给g_num。经过一番折腾,我们明明做了两次加1的运算,结果g_num却是101,导致了错误的产生。通常,周期越多,误差越大。这时候我们可以加一把锁。

  acquire() — 锁定资源,此时资源是锁定状态,其他线程无法修改锁定的资源,直到等待锁定的资源释放之后才能操作;

  release() — 释放资源,也称为解锁操作,对锁定的资源解锁,解锁之后其他线程可以对资源正常操作;

  以上面的代码为例:如果想得到一个正确的结果,可以在全局变量加1之前直接使用互斥锁锁定资源,计算完成后再释放资源。这是一个完整的计算过程。至于应该先执行哪个线程,这并不重要。先到先得,你可以根据自己的能力发言.演示代码如下:

  #开发时间:2022年1月27日12:59

  导入线程

  r

  esult = 0 # 定义全局变量result

  mutex = threading.Lock()

  def work1(num):

   global result

   mutex.acquire()

   for i in range(num):

   result += 1

   print(------from work1-------, result)

   mutex.release()

  def work2(num):

   global result

   mutex.acquire()

   for i in range(num):

   result += 1

   print(------from work2-------, result)

   mutex.release()

  def main():

   print(--------begin----------, result)

   # 创建两个线程

   t1 = threading.Thread(target=work1, args=(100000000,))

   t2 = threading.Thread(target=work1, args=(100000000,))

   t1.start()

   t2.start()

  if __name__ == __main__:

   main()

  

  我们来看一下结果:

  

--------begin---------- 0

  ------from work1------- 100000000

  ------from work1------- 200000000

  

  

  

三、死锁问题

  1.单个互斥锁的死锁:

  acquire()/release() 是成对出现的,互斥锁对资源锁定之后就一定要解锁,否则资源会一直处于锁定状态,其他线程无法修改;就好比上面的代码,任何一个线程没有释放资源release(),程序就会一直处于阻塞状态(在等待资源被释放),不信你可以试一试~

  2.多个互斥锁的死锁:

  在同时操作多个互斥锁的时候一定要格外小心,因为一不小心就容易进入死循环,假如有这样一个场景:boss让程序员一实现功能一的开发,让程序员二实现功能二的开发,功能开发完成之后一起整合代码!

  

# 导入线程threading模块

  import threading

  # 导入线程time模块

  import time

  # 创建互斥锁

  mutex_one = threading.Lock()

  mutex_two = threading.Lock()

  def programmer_thread1():

   mutex_one.acquire()

   print("我是程序员1,module1开发正式开始,程序一加锁,程序二加锁")

   time.sleep(2)

   # 此时会堵塞,因为这个mutex_two已经被线程programmer_thread2抢先上锁了,等待解锁

   mutex_two.acquire()

   print("等待程序员2通知我合并代码")

   mutex_two.release()

   print(程序员2开发完了,程序员1释放第二把锁)

   mutex_one.release()

   print(程序员1开发完了,程序员1释放第一把锁)

  def programmer_thread2():

   mutex_two.acquire()

   print("我是程序员2,module2开发正式开始,程序二加锁,程序一加锁")

   time.sleep(2)

   # 此时会堵塞,因为这个mutex_one已经被线程programmer_thread1抢先上锁了,等待解锁

   #mutex_two.release()

   mutex_one.acquire()

   print("等待程序员1通知我合并代码")

   mutex_one.release()

   print(程序员2释放第一把锁)

   # mutex_two.release()

   print(程序员2释放第二把锁)

  def main():

   t1 = threading.Thread(target=programmer_thread1)

   t2 = threading.Thread(target=programmer_thread2)

   # 启动线程

   t1.start()

   t2.start()

   # 阻塞函数,等待线程结束

   t1.join()

   t2.join()

   # 整合代码结束

   print("整合代码结束 ")

  if __name__ == "__main__":

   main()

  

  分析下上面代码:程序员1在等程序员2通知,程序员2在等程序员1通知,两个线程都陷入阻塞中,因为两个线程都在等待对方解锁,这就是死锁!所以在开发中对于死锁的问题还是需要多多注意!

  

  

总结

  到此这篇关于python多线程互斥锁与死锁问题详解的文章就介绍到这了,更多相关python互斥锁与死锁内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: