python 线程死锁_python多线程死锁和可重入锁的简单示例

对python这个高级语言感兴趣的小伙伴,下面一起跟随编程之家 jb51.cc的小编两巴掌来看看吧!

死锁

在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。尽管死锁很少发生,但一旦发生就会造成应用的停止响应。下面看一个死锁的例子:

# @param python多线程编程4: 死锁和可重入锁

# @author 编程之家 jb51.cc|512Pic.com

# encoding: UTF-8

import threading

import time

class MyThread(threading.Thread):

def do1(self):

global resA,resB

if mutexA.acquire():

msg = self.name+' got resA'

print msg

if mutexB.acquire(1):

msg = self.name+' got resB'

print msg

mutexB.release()

mutexA.release()

def do2(self):

global resA,resB

if mutexB.acquire():

msg = self.name+' got resB'

print msg

if mutexA.acquire(1):

msg = self.name+' got resA'

print msg

mutexA.release()

mutexB.release()

def run(self):

self.do1()

self.do2()

resA = 0

resB = 0

mutexA = threading.Lock()

mutexB = threading.Lock()

def test():

for i in range(5):

t = MyThread()

t.start()

if __name__ == '__main__':

test()

# End www.jb51.cc

执行结果:

Thread-1 got resA

Thread-1 got resB

Thread-1 got resB

Thread-1 got resA

Thread-2 got resA

Thread-2 got resB

Thread-2 got resB

Thread-2 got resA

Thread-3 got resA

Thread-3 got resB

Thread-3 got resB

Thread-3 got resA

Thread-5 got resA

Thread-5 got resB

Thread-5 got resB

Thread-4 got resA

此时进程已经死掉。

可重入锁

更简单的死锁情况是一个线程“迭代”请求同一个资源,直接就会造成死锁:

# @param python多线程编程4: 死锁和可重入锁

# @author 编程之家 jb51.cc|512Pic.com

import threading

import time

class MyThread(threading.Thread):

def run(self):

global num

time.sleep(1)

if mutex.acquire(1):

num = num+1

msg = self.name+' set num to '+str(num)

print msg

mutex.acquire()

mutex.release()

mutex.release()

num = 0

mutex = threading.Lock()

def test():

for i in range(5):

t = MyThread()

t.start()

if __name__ == '__main__':

test()

# End www.jb51.cc

为了支持在同一线程中多次请求同一资源,python提供了“可重入锁”:threading.RLock。RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。上面的例子如果使用RLock代替Lock,则不会发生死锁:

# @param python多线程编程4: 死锁和可重入锁

# @author 编程之家 jb51.cc|512Pic.com

import threading

import time

class MyThread(threading.Thread):

def run(self):

global num

time.sleep(1)

if mutex.acquire(1):

num = num+1

msg = self.name+' set num to '+str(num)

print msg

mutex.acquire()

mutex.release()

mutex.release()

num = 0

mutex = threading.RLock()

def test():

for i in range(5):

t = MyThread()

t.start()

if __name__ == '__main__':

test()

# End www.jb51.cc

执行结果:

Thread-1 set num to 1

Thread-3 set num to 2

Thread-2 set num to 3

Thread-5 set num to 4

Thread-4 set num to 5

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

如您喜欢交流学习经验,点击链接加入交流1群:1065694478(已满)交流2群:163560250

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值