避开死锁

代码程序中,尽量要避免死锁的产生,下面分析常见的线程锁使用方式 ;注:只有同一把锁才会产生互斥

1、常见的死锁方式(加锁时程序报错,锁未释放):

import time
import threading class Lock():
def __init__(self):
self.mutex = threading.Lock() def error(self):
try:
self.mutex.acquire()
a = '1'
b = 2
print(a+b)
self.mutex.release()
except Exception as e:
print(e) def safe(self):
try:
self.mutex.acquire()
a = 1
b = 2
print(a + b)
self.mutex.release()
except Exception as e:
print(e) def func1(cls):
while True:
cls.safe()
time.sleep(0.1) def func2(cls):
while True:
cls.error()
time.sleep(0.1) if __name__ == '__main__':
lock = Lock()
t1 = threading.Thread(target=func1,args=(lock,))
t1.start()
t2 = threading.Thread(target=func2,args=(lock,))
t2.start() # 3
# must be str, not int

执行上面代码,异常抛出时,锁未释放,程序卡死

2、修补代码死锁情况(抛异常处添加锁释放):

import time
import threading class Lock():
def __init__(self):
self.mutex = threading.Lock() def error(self):
try:
self.mutex.acquire()
a = '1'
b = 2
print(a+b)
self.mutex.release()
except Exception as e:
print(e)
self.mutex.release() def safe(self):
try:
self.mutex.acquire()
a = 1
b = 2
print(a + b)
self.mutex.release()
except Exception as e:
print(e) def func1(cls):
while True:
cls.safe()
time.sleep(0.1) def func2(cls):
while True:
cls.error()
time.sleep(0.1) if __name__ == '__main__':
lock = Lock()
t1 = threading.Thread(target=func1,args=(lock,))
t1.start()
t2 = threading.Thread(target=func2,args=(lock,))
t2.start() # 3
# must be str, not int
# must be str, not int
# 3
# 3

  

 3、最佳方案(不用手动释放,即使异常也会自动释放):

import time
import threading class Lock():
def __init__(self):
self.mutex = threading.Lock() def error(self):
try:
with self.mutex:
a = '1'
b = 2
print(a+b)
except Exception as e:
print(e) def safe(self):
try:
with self.mutex:
a = 1
b = 2
print(a + b)
except Exception as e:
print(e) def func1(cls):
while True:
cls.safe()
time.sleep(0.1) def func2(cls):
while True:
cls.error()
time.sleep(0.1) if __name__ == '__main__':
lock = Lock()
t1 = threading.Thread(target=func1,args=(lock,))
t1.start()
t2 = threading.Thread(target=func2,args=(lock,))
t2.start() # 3
# must be str, not int
# 3
# must be str, not int
# 3
# must be str, not int

  

Python开发【笔记】:加锁的最佳方案的更多相关文章

  1. python开发笔记-通过xml快捷获取数据

    今天在做下python开发笔记之如何通过xml快捷获取数据,下面以调取nltk语料库为例: import nltk nltk.download() showing info https://raw.g ...

  2. python开发笔记-python调用webservice接口

    环境描述: 操作系统版本: root@9deba54adab7:/# uname -a Linux 9deba54adab7 --generic #-Ubuntu SMP Thu Dec :: UTC ...

  3. python开发笔记-Python3.7+Django2.2 Docker镜像搭建

    目标镜像环境介绍: 操作系统:ubuntu16.04 python版本:python 3.7.4 django版本:2.2 操作步骤: 1.  本地安装docker环境(略)2. 拉取ubunut指定 ...

  4. python开发笔记之zip()函数用法详解

    今天分享一篇关于python下的zip()函数用法. zip()是Python的一个内建函数,它接受一系列可迭代的对象作为参数,将对象中对应的元素按顺序组合成一个tuple,每个tuple中包含的是原 ...

  5. Python开发笔记之正则表达式的使用

    查找正则表达式 import re re_txt = re.compile(r'(\d)*.txt') m = re_txt.search(src) if not m == None: m.group ...

  6. python开发笔记-类

    类的基本概念: 问题空间:问题空间是问题解决者对一个问题所达到的全部认识状态,它是由问题解决者利用问题所包含的信息和已贮存的信息主动的地构成的. 初始状态:一开始时的不完全的信息或令人不满意的状况: ...

  7. Python开发笔记之-浮点数传输

    操作系统 : CentOS7.3.1611_x64 gcc版本 :4.8.5 Python 版本 : 2.7.5 思路如下 : 1.将浮点数a通过内存拷贝,赋值给相同字节的整型数据b: 2.将b转换为 ...

  8. Python开发笔记:网络数据抓取

    网络数据获取(爬取)分为两部分: 1.抓取(抓取网页) · urlib内建模块,特别是urlib.request · Requests第三方库(中小型网络爬虫的开发) · Scrapy框架(大型网络爬 ...

  9. python开发笔记-ndarray方法属性详解

    Python中的数组ndarray是什么? 1.NumPy中基本的数据结构 2.所有元素是同一种类型 3.别名是array 4.利于节省内存和提高CPU计算时间 5.有丰富的函数 ndarray的创建 ...

随机推荐

  1. 使用tinyproxy搭建http代理

    一.前言   二.搭建环境 * Linux laptop 2.6.32-45-generic #100-Ubuntu SMP Wed Nov 14 10:41:11 UTC 2012 i686 GNU ...

  2. Nginx 过期时间

    客户端(浏览器)访问服务器上的资源后,会缓存在浏览器中,对于一些经常变更的静态资源,我们可以设置缓存时间,也就是设置静态资源的过期时间 [root@localhost ~]$ cat /usr/loc ...

  3. 团购已满,O2O只是个笑话吗?

    团购的用户习惯经过多年的“发酵”以后,大多数用户的团购习惯已经养成,同样一张电影票团购和直接现场购买的差价在一倍以上,当然O2O领域的其他情况也差不多,面对明显的“优惠”,用户当然乐意使用团购服务. ...

  4. Elasticseach的评分机制

    lucene 的评分机制 elasticsearch是基于lucene的,所以他的评分机制也是基于lucene的.评分就是我们搜索的短语和索引中每篇文档的相关度打分. 如果没有干预评分算法的时候,每次 ...

  5. 使用java中的session来记录访问次数

    <%@ page import="java.net.CookieHandler" %><%-- Created by IntelliJ IDEA. User: D ...

  6. Java实现简单的正则表达式匹配

    import java.util.regex.Pattern; public class Test_REG { public static void main(String[] args) { //只 ...

  7. HashTable、HashMap、ConcurrentHashMap、Collections.synchronizedMap()区别

    Collections.synchronizedMap()和Hashtable一样,实现上在调用map所有方法时,都对整个map进行同步,而ConcurrentHashMap的实现却更加精细,它对Ha ...

  8. 《转载》图解Tomcat类加载机制

    本文转载自http://www.cnblogs.com/xing901022/p/4574961.html 说到本篇的tomcat类加载机制,不得不说翻译学习tomcat的初衷. 之前实习的时候学习j ...

  9. Linux用户态程序计时方式详解

    前言 良好的计时器可帮助程序开发人员确定程序的性能瓶颈,或对不同算法进行性能比较.但要精确测量程序的运行时间并不容易,因为进程切换.中断.共享的多用户.网络流量.高速缓存访问及转移预测等因素都会对程序 ...

  10. Find–atime –ctime –mtime的用法与区别总结

    转自 周五有同事问起find命令中-mtime n.-mtime –n以及-mtime +n的用法区别,当时虽然记得这里n是n个24个小时的意思,也是对所有这几个属性详细的用法却一知半解,索性周末仔细 ...