48_并发编程-线程-资源共享/锁

一、数据共享
  多个线程内部有自己的数据栈,数据不共享;全局变量在多个线程之间是共享的。
 1 # 线程数据共享不安全加锁
 2 
 3 import time
 4 from threading import Thread, Lock
 5 
 6 
 7 num = 100
 8 
 9 def func(t_lock):
10     global num
11     t_lock.acquire()
12     mid = num
13     mid -= 1
14     time.sleep(0.01) # 设置一个时间,模拟数据修改时,先从内存中拿出作修改,在把结果放回去的时间差
15     num = mid
16     t_lock.release()
17 
18 if __name__ == '__main__':
19 
20     t_lock = Lock()
21 
22     t_lst = []
23     for i in range(10):
24         t_thread = Thread(target=func, args=(t_lock,))    
25         t_lst.append(t_thread)
26         t_thread.start()
27     [t_obj.join() for t_obj in t_lst]    #必须加join,因为主线程和子线程不一定谁快,一般都是主线程快一些,所有我们要等子线程执行完毕才能看出效果    
28 
29     print('主线程结束!', num)    # 结果为90
数据共享实例
二、同步锁(互斥锁) - 产生死锁
  进程也有死锁与递归锁,在进程那里忘记说了,放到这里一切说了额,进程的死锁和线程的是一样的,而且一般情况下进程之间是数据不共享的,不需要加锁,由于线程是对全局的数据共享的,所以对于全局的数据进行操作的时候,要加锁。
  死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程,如下就是死锁
 1 from threading import Thread,Lock
 2 import time
 3 
 4 class MyThread(Thread):
 5     def run(self):
 6         self.func1()
 7         self.func2()
 8     def func1(self):
 9         mutexA.acquire()
10         print('\033[41m%s 拿到A锁>>>\033[0m' %self.name)
11         mutexB.acquire()
12         print('\033[42m%s 拿到B锁>>>\033[0m' %self.name)
13         mutexB.release()
14         mutexA.release()
15 
16     def func2(self):
17         mutexB.acquire()  
18         print('\033[43m%s 拿到B锁???\033[0m' %self.name)
19         time.sleep(2)
20 #分析:当线程1执行完func1,然后执行到这里的时候,拿到了B锁,线程2执行func1的时候拿到了A锁,那么线程2还要继续执行func1里面的代码,再去拿B锁的时候,发现B锁被人拿了,那么就一直等着别人把B锁释放,那么就一直等着,等到线程1的sleep时间用完之后,线程1继续执行func2,需要拿A锁了,但是A锁被线程2拿着呢,还没有释放,因为他在等着B锁被释放,那么这俩人就尴尬了,你拿着我的老A,我拿着你的B,这就尴尬了,俩人就停在了原地
21         
22         mutexA.acquire()
23         print('\033[44m%s 拿到A锁???\033[0m' %self.name)
24         mutexA.release()
25         mutexB.release()
26 
27 if __name__ == '__main__':
28 
29     mutexA=Lock()    # 同步锁必须这样创建
30     mutexB=Lock()
31     for i in range(10):
32         t=MyThread()
33         t.start()
34 
35 '''
36 Thread-1 拿到A锁>>>
37 Thread-1 拿到B锁>>>
38 Thread-1 拿到B锁???
39 Thread-2 拿到A锁>>>
40 然后就卡住,死锁了
41 '''
死锁现象

三、解决死锁方案 - 递归锁
  解决方法,递归锁,在Python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock。
  这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。上面的例子如果使用RLock代替Lock,则不会发生死锁:
 1 import time
 2 from threading import Thread,RLock
 3 
 4 
 5 class MyThread(Thread):
 6 
 7     def __init__(self, lockA, lockB):
 8         super().__init__()
 9         self.lockA = lockA
10         self.lockB = lockB
11     def run(self):
12         self.func1()
13         self.func2()
14 
15     def func1(self):
16         self.lockA.acquire()
17         print('我是func1')
18         self.lockB.acquire()
19         print('func1中有其他事')
20         self.lockB.release()
21         self.lockA.release()
22 
23     def func2(self):
24         self.lockB.acquire()
25         print('我是func2')
26         time.sleep(0.5)
27         self.lockA.acquire()
28         print('func2中有什么事')
29         self.lockA.release()
30         self.lockB.release()
31 
32 if __name__ == '__main__':
33 
34     lockA = lockB = RLock()
35 
36     t1 = MyThread(lockA, lockB)
37     t1.start()
38     t2 = MyThread(lockA, lockB)
39     t2.start()
40     print('嗯嗯,两人不错')
递归锁

转载于:https://www.cnblogs.com/hq82/p/9858375.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/450897.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

移动硬盘提示无法访问设备硬件出现致命错误,导致请求失败的资料寻回方案

J盘打不开设备硬件出现致命错误,导致请求失败,是因为这个I盘的文件系统内部结构损坏导致的。要恢复里面的数据就必须要注意,这个盘不能格式化,否则数据会进一步损坏。具体的恢复方法看正文 工具/软件:星空数据恢复软件 步骤1&…

VMware10上新建虚拟机步骤图解

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 第一种 : 自定义方式: 安装虚拟机的过程步骤,基本上过程的每一步都有截图,跟着过程就可以很容易的创…

怎么理解 IaaS、SaaS 和 PaaS 的区别?

原文链接:怎么理解 IaaS、SaaS 和 PaaS 的区别? 一、定义层面的区别 SaaS、PaaS、IaaS简单的说都属于云计算服务,也就是云计算服务。我们对于云计算的概念,维基百科有以下定义: Cloud computing is a new form of In…

三星“打法”:先模仿对手 再吃掉对手

台湾地区电子业者将三星视为“台湾公敌”,事实上,它几乎是全球电子业者的敌人。 这家韩国电子业巨头十年之间夺取了日本企业在这一领域中纵横30年的荣光,更是建立起了令人叹为观止的垂直整合帝国。 韩国政府的大力支持、日元升值韩元贬值等均…

SharpZipLib 压缩ZIP导出

1      var uploadSectionDir Path.Combine("Upload", "QQ", DateTime.Now.ToString("yyyyMMdd"));2 string uploadDir Path.Combine(HttpRuntime.AppDomainAppPath, uploadSectionDir);3 if (!Directory.Exi…

java动态调用c++库

前言 最近在做一个通过java程序调用c动态语言库,在网上百度,谷歌找了诸多例子,还是屡试不爽。经过一番折腾还是披荆斩棘,创出一条道路。希望分享给正在迷茫的朋友们... 使用的环境 spring boot gradle JNI介绍 JNI全拼是Java Nat…

如何删除虚拟机上的操作系统、删除新建的虚拟机

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 打开VMware,我安装了三个虚拟系统,要对win98进行删除,从磁盘上删除~~ 2、双击你要删除的系统&#xf…

什么是QoS技术

QoS(Quality of Service)是服务质量的简称。从传统意义上来讲,无非就是传输的带宽、传送的时延、数据的丢包率等,而提高服务质量无非也就是保证传输的带宽,降低传送的时延,降低数据的丢包率以及时延抖动等。…

一套完整的用户增长系统架构

互联网的世界里一切都是为了增长,灵光一现的创新可能会让一个产品成功,但绝不可能长久。 在用户增长的领域里,如何复用一套框架,找到最佳实践的一条路径,再配备一点运气,去实现商业成功是我一直所探索的话题…

编译性语言、解释性语言和脚本语言

什么是编译性语言、解释性语言和脚本语言 计算机不能直接理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能值型高级语言编写的程序。  翻译的方式有两种,一个是编译,一个是解释。…

对多租户的理解

一、 多租户定义 多租户定义: 多租户技术或称多重租赁技术,简称SaaS,是一种软件架构技术,是实现如何在多用户环境下(此处的多用户一般是面向企业用户)共用相同的系统或程序组件,并且可确保各用…

查看VMware上虚拟机的 ip 地址

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 1. 开启虚拟机: 2.输入账号密码登陆到虚拟机中 3. 选择 xxx Home 右键---- Open in Terinal 进入命令行页面 ----- 输入命令…

Hibernate之表间关系

ManyToOne 多对一,是最常见的表间关系,对应关系数据库中的外键关系。通常用于建立子实体和其父实体的关联关系 Entity(name "Person") public static class Person {IdGeneratedValueprivate Long id;//Getters and setters are omitted for …

Python大神告诉你,学习Python应该读哪些书!

关注头条号,私信回复资料会有意外惊喜呦………………最后一张照片有资料呦。在传统的Web开发之外的领域,Python开发人员的就业机会越来越多,无论你是初学者还是大神,现在正是投入到Python学习的好时机。一个IBM的博客文章报道了如…

脚本语言

脚本语言(Script language,scripting language,scripting programming language)是为了缩短传统的编写-编译-链接-运行(edit-compile-link-run)过程而创建的计算机编程语言。此命名起源于一个脚本“screenp…

Java Agent

一、什么是 Java Agent ? 笼统地来讲,Java Agent 是一个统称,该功能是 Java 虚拟机提供的一整套后门。通过这套后门可以对虚拟机方方面面进行监控与分析。甚至干预虚拟机的运行。 Java Agent 又叫做 Java 探针,Java Agent 是在 …

JDK 1.8 官网下载地址(linux / windows)

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 JDK 1.8 官网下载地址: JDK 1.8 官网下载地址(linuxwindows) 上面连接可以直接点击,连接…

跟着太白老师学python day11 可迭代对象和迭代器

如果对象的属性中有__iter__属性就说明是可迭代的,容器类的数据类型都是可迭代对象 如果对象的属性中既有__iter__属性也有__next__属性,就说明这个对象是迭代器 如何判断一个函数是不是可迭代的,是不是迭代器 方法一 s 123 print(__iter__ …

搅局者奇虎360:特供机背后的周式隐忧

摘要:从未涉足制造,将来也“绝不参与制造”的360,却声称要进军智能手机。从未涉足制造,将来也“绝不参与制造”的360,却声称要进军智能手机。 5月4日晚间,“长达半年的思考”后,奇虎360董事长周…

数据结构基础入门知识

数据结构基础入门知识 ------ 数据结构:理解和练习《异类-不一样的成功启示录》IP/26 192IP/25 128IP/24192.12864 3216 2 1 NTP:时间同步服务器高手都是最仔细的,严谨的 telnet 查看某个端口是否可用,是否是开启状态的要有探索冒险的精神 --…