#### 死鎖
##### 1. 死鎖
在線程間共享多個資源的時候,如果兩個線程分別占有一部分資源并且同時等待對方的資源,就會造成死鎖。
盡管死鎖很少發生,但一旦發生就會造成應用的停止響應。下面看一個死鎖的例子
~~~
#coding=utf-8
import threading
import time
class MyThread1(threading.Thread):
def run(self):
if mutexA.acquire():
print(self.name+'----do1---up----')
time.sleep(1)
if mutexB.acquire():
print(self.name+'----do1---down----')
mutexB.release()
mutexA.release()
class MyThread2(threading.Thread):
def run(self):
if mutexB.acquire():
print(self.name+'----do2---up----')
time.sleep(1)
if mutexA.acquire():
print(self.name+'----do2---down----')
mutexA.release()
mutexB.release()
mutexA = threading.Lock()
mutexB = threading.Lock()
if __name__ == '__main__':
t1 = MyThread1()
t2 = MyThread2()
t1.start()
t2.start()
~~~
運行結果:

此時已經進入到了死鎖狀態,可以使用ctrl-z退出
##### 2. 說明

##### 3. 避免死鎖
* 程序設計時要盡量避免(銀行家算法)
* 添加超時時間等
##### 附錄-銀行家算法
###### [背景知識]
一個銀行家如何將一定數目的資金安全地借給若干個客戶,使這些客戶既能借到錢完成要干的事,同時銀行家又能收回全部資金而不至于破產,這就是銀行家問題。這個問題同操作系統中資源分配問題十分相似:銀行家就像一個操作系統,客戶就像運行的進程,銀行家的資金就是系統的資源。
###### [問題的描述]
一個銀行家擁有一定數量的資金,有若干個客戶要貸款。每個客戶須在一開始就聲明他所需貸款的總額。若該客戶貸款總額不超過銀行家的資金總數,銀行家可以接收客戶的要求。客戶貸款是以每次一個資金單位(如1萬RMB等)的方式進行的,客戶在借滿所需的全部單位款額之前可能會等待,但銀行家須保證這種等待是有限的,可完成的。
例如:有三個客戶C1,C2,C3,向銀行家借款,該銀行家的資金總額為10個資金單位,其中C1客戶要借9各資金單位,C2客戶要借3個資金單位,C3客戶要借8個資金單位,總計20個資金單位。某一時刻的狀態如圖所示。

對于a圖的狀態,按照安全序列的要求,我們選的第一個客戶應滿足該客戶所需的貸款小于等于銀行家當前所剩余的錢款,可以看出只有C2客戶能被滿足:C2客戶需1個資金單位,小銀行家手中的2個資金單位,于是銀行家把1個資金單位借給C2客戶,使之完成工作并歸還所借的3個資金單位的錢,進入b圖。同理,銀行家把4個資金單位借給C3客戶,使其完成工作,在c圖中,只剩一個客戶C1,它需7個資金單位,這時銀行家有8個資金單位,所以C1也能順利借到錢并完成工作。最后(見圖d)銀行家收回全部10個資金單位,保證不賠本。那麼客戶序列{C1,C2,C3}就是個安全序列,按照這個序列貸款,銀行家才是安全的。否則的話,若在圖b狀態時,銀行家把手中的4個資金單位借給了C1,則出現不安全狀態:這時C1,C3均不能完成工作,而銀行家手中又沒有錢了,系統陷入僵持局面,銀行家也不能收回投資。
綜上所述,銀行家算法是從當前狀態出發,逐個按安全序列檢查各客戶誰能完成其工作,然后假定其完成工作且歸還全部貸款,再進而檢查下一個能完成工作的客戶,......。如果所有客戶都能完成工作,則找到一個安全序列,銀行家才是安全的。
- 系統編程
- 1.進程
- 1.1.fork
- 1.2.多個進程能否修改全局變量
- 1.3多次fork的問題
- 1.4.進程的創建-multiprocessing
- 1.5.進程的創建-Process子類
- 1.6.進程池Pool
- 1.7.進程間通信--Queue
- 2.線程
- 2.1.多線程-Threading
- 2.2.threading注意點
- 2.3.多線程-共享全局變量
- 2.4.線程和進程的對比
- 2.5.同步
- 2.6.互斥鎖
- 2.7.多線程-非共享數據
- 2.8.死鎖
- 2.9.同步應用
- 2.10.生產者與消費者模式
- 2.11.ThreadLocal
- 2.12.異步
- 2.13.GIL的問題
- 網絡編程
- 1.網絡概述-udp
- 1.1.TCP/IP
- 1.2.端口
- 1.3.ip地址
- 1.4.socket簡介
- 1.5.UDP介紹
- 1.6.udp網絡程序-發送數據
- 1.7.udp網絡程序-發送、接收數據
- 1.8.udp網絡程序-端口問題
- 1.9.udp綁定信息
- 2.0.udp網絡通信過程
- 2.1.udp應用:echo服務器
- 2.2.udp應用:聊天室
- 2.3.udp總結
- 2.4.udp綜合-模擬QQ
- 2.TFTP下載和上傳
- 3.TCP/IP
- 3.1.打開瀏覽器訪問百度的過程
- web服務器
- 1.1.MyWebServer.py
- 1.2.MyWebFramework.py
- 正則
- 1.1.re模塊
- 1.2.字符
- 1.3.原始字符串
- 1.4.表示數量
- 1.5.表示邊界
- 1.6.匹配分組
- 1.7.貪婪和非貪婪
- 數據結構和算法
- 1.引入概念
- 1.1.第一次嘗試
- 1.2.算法的提出
- 1.3.第二次嘗試
- 1.4.算法效率衡量
- 1.5.算法分析
- 1.6.常見時間復雜度
- 1.7.python內置類型性能分析
- 1.8.數據結構
- 2.順序表
- 2.1.順序表的形式
- 2.2.順序表的結構和實現
- 2.3.順序表的操作
- 2.4.python中的順序表
- 3.鏈表
- 3.1.單向鏈表
- 3.2.單向循環鏈表
- 3.3.雙向鏈表
- 4.棧
- 4.1.棧的結構實現
- 5.隊列
- 5.1.隊列的實現
- 5.2.雙端隊列
- 6.排序和搜索
- 6.1.冒泡排序
- 6.2.選擇排序
- 6.3.插入排序
- 6.4.快速排序
- 6.5.哈希排序
- 6.6.歸并排序
- 6.7.常見排序算法效率比較
- 6.8.搜索
- 7.樹與樹算法
- 7.1.二叉樹
- 7.2.二叉樹的遍歷
- 初識Django
- 1.小白
- 2.初次嘗試
- 3.管理站點
- 4.視圖
- 5.模板
- django模型
- 1.定義模型
- 2.模型成員
- 3.模型查詢
- 4.自連接
- django視圖
- django模板
- django高級
- django第三方
- django-git