避开死锁

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

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. 【代码审计】EasySNS_V1.6 前台XSS跨站脚本漏洞分析

    0x00 环境准备 EasySNS官网:http://www.imzaker.com/ 网站源码版本:EasySNS极简社区V1.60 程序源码下载:http://es.imzaker.com/ind ...

  2. 用MyEclipse将Maven Dependencies中的jar包导出

    1.右击pom.xml文件,选择Run As  ——> Maven build… 2.在打开的页面中,如图输入“dependency:copy-dependencies”,后点击“Run”即可 ...

  3. SpringMVC实现多文件(批量)上传

    1.springMVC实现多文件上传需要的包如图2.webroot下的结构如图所示 3.java代码: package cn.lxc.controller; import java.io.File; ...

  4. Android中实现定时器的3中方法

    在Android开发中,定时器一般有以下3种实现方法: 一.采用Handler与线程的sleep(long)方法: 二.采用Handler的postDelayed(Runnable, long)方法: ...

  5. SQL - 根据天来分组比较

    SELECT COUNT(*) FROM (SELECT WeixinUserID,CONVERT(varchar(100),CreateTime, 23) AS DT FROM SiteVisite ...

  6. Python学习(24):Python面向对象(2)

    转自 http://www.cnblogs.com/BeginMan/p/3191037.html 一.类 类就是一个数据结构,封装了数据和操作. 类的声明与函数的声明十分类似: class newC ...

  7. Android英文文档翻译系列(6)——LocalBroadcastManager

    public class LocalBroadcastManager extends Object java.lang.Object    ↳ android.support.v4.content.L ...

  8. sea.js常用接口

    seajs.config 用来对 Sea.js 进行配置. seajs.config({ // 指定需要使用的插件 plugins: ['text', 'shim'], // 设置别名,方便调用 al ...

  9. 【Java基础系列】Java IO系统

    前言 创建好的输入/输出系统不仅要考虑三种不同种类的IO系统(文件,控制台,网络连接)还需要通过大量不同的方式与他们通信(顺序,随机访问,二进制,字符,按行,按字等等). 一.输入和输出 Java的I ...

  10. 【css系列】创建网页加载进度条

    一.最简单或者明显的方式是使用定时器 1.在网页中加入布局覆盖真实网页内容 2.使用定时器确定加载所用时间的长短,其实并不是真正的加载进度实现 <!DOCTYPE html> <ht ...