死鎖和可重入鎖
死鎖
線上程間共享多個資源的時候,如果兩個執行緒分別佔有一部分資源並且同時等待對方的資源,就會造成死鎖。儘管死鎖很少發生,但一旦發生就會造成應用的停止響應。下面看一個死鎖的例子:
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()
執行結果:
> 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
此時程式已經死掉。
可重入鎖
更簡單的死鎖情況是一個執行緒“迭代”請求同一個資源,直接就會造成死鎖:
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()
為了支援在同一執行緒中多次請求同一資源,python提供了“可重入鎖”:threading.RLock。RLock內部維護著一個Lock和一個counter變數,counter記錄了acquire的次數,從而使得資源可以被多次require。直到一個執行緒所有的acquire都被release,其他的執行緒才能獲得資源。上面的例子如果使用RLock代替Lock,則不會發生死鎖:
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()
執行結果:
> 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
相關文章
- 可重入鎖與不可重入鎖理解
- 可重入鎖
- redis分散式鎖-可重入鎖Redis分散式
- java重入鎖、公平鎖和非公平鎖Java
- 可重入鎖原始碼分析原始碼
- Redisson 分散式鎖原始碼 01:可重入鎖加鎖Redis分散式原始碼
- ZooKeeper 分散式鎖 Curator 原始碼 02:可重入鎖重複加鎖和鎖釋放分散式原始碼
- Java併發-顯式鎖篇【可重入鎖+讀寫鎖】Java
- Golang可重入鎖的實現Golang
- ZooKeeper 分散式鎖 Curator 原始碼 01:可重入鎖分散式原始碼
- Java 種15種鎖的介紹:公平鎖,可重入鎖,獨享鎖,互斥鎖等等Java
- Java 種15種鎖的介紹:公平鎖,可重入鎖,獨享鎖,互斥鎖等等...Java
- ReentrantLock可重入鎖、公平鎖非公平鎖區別與實現原理ReentrantLock
- ZooKeeper 分散式鎖 Curator 原始碼 03:可重入鎖併發加鎖分散式原始碼
- 自旋鎖、阻塞鎖、可重入鎖、悲觀鎖、樂觀鎖、讀寫鎖、偏向所、輕量級鎖、重量級鎖、鎖膨脹、物件鎖和類鎖物件
- MySQL 死鎖和鎖等待MySql
- ReentrantLock可重入鎖——原始碼詳解ReentrantLock原始碼
- Java 中15種鎖的介紹:公平鎖,可重入鎖,獨享鎖,互斥鎖,樂觀鎖,分段鎖,自旋鎖等等Java
- Lock鎖之重入鎖與讀寫鎖
- Redis實現可重入的分散式鎖Redis分散式
- Go 為什麼不支援可重入鎖?Go
- Mysql 兩階段鎖和死鎖MySql
- mysql行鎖和死鎖檢測MySql
- 如何避免死鎖和活鎖? - simar
- 重入鎖的理解
- 死鎖是什麼?如何預防和避免死鎖?
- java中如何實現可重入的自旋鎖Java
- Java併發基礎-鎖的使用及原理(可重入鎖、讀寫鎖、內建鎖、訊號量等)Java
- Lock介面、重入鎖ReentrantLock、讀寫鎖ReentrantReadWriteLockReentrantLock
- 淺談Java中的鎖:Synchronized、重入鎖、讀寫鎖Javasynchronized
- synchronized鎖重入問題synchronized
- 死鎖
- MySQL:MTS和mysqldump死鎖MySql
- 【java併發程式設計】ReentrantLock 可重入讀寫鎖Java程式設計ReentrantLock
- 【Java】深入理解ReentrantLock可重入鎖之簡單使用JavaReentrantLock
- Java 重入鎖 ReentrantLock 原理分析JavaReentrantLock
- 什麼是死鎖?如何解決死鎖?
- ReentrantLock(重入鎖)功能詳解和應用演示ReentrantLock