在使用用的過程中需要匯入threading模組的lock類
當多個執行緒幾乎同時修改某乙個共享資料的時候,需要進行同步控制
執行緒同步能夠保證多個執行緒安全訪問競爭資源,最簡單的同步機制是引入互 斥鎖。
互斥鎖為資源引入乙個狀態:鎖定/非鎖定。
建立鎖、鎖定鎖、釋放鎖
from threading importlock
#建立鎖
mutex =lock()
#獲取鎖(上鎖)
mutex.acquire()
#釋放鎖(解鎖)
mutex.release()
在鎖定鎖的過程中acquire()方法可以接受乙個blocking引數,
如果設定blocking為true,則當前執行緒會堵塞,直到獲取到這個鎖為止(如果沒有 指定,那麼預設為true)
如果設定blocking為false,則當前執行緒不會堵塞
上鎖和解鎖的過程(假設是多執行緒排程):
這個鎖一般是為共享資源服務的,即多個執行緒同時使用共享資源。這個鎖同一時間只能有乙個執行緒排程,其他執行緒阻塞,只有當前排程的執行緒釋放這個鎖,阻塞的執行緒才能排程。
鎖的優點:
確保了某段關鍵**只能有乙個執行緒從頭到尾完整的執行。
鎖的缺點:
組織了多執行緒的併發執行,包含鎖的某段**實際上只能以單執行緒模式執行,效率就大大的降低了;**中可能存在多個鎖,如果多個執行緒擁有多個鎖,容易造成死鎖。
死鎖的現象(例項):
#死鎖 兩者都沒有釋放對方需要的鎖,而釋放的條件恰好是獲取對方釋放所需要的鎖
#執行緒1
class
mythread1(threading.thread):
def__init__
(self):
super().
__init__
()
defrun(self):
#執行緒1獲取a鎖
ifmutexa.acquire():
print(self.name+"
-----do1---up-----")
sleep(1)
#此時執行緒2獲取了b鎖,需要等待執行緒2釋放b鎖
ifmutexb.acquire():
print(self.name + "
-----do1---down-----")
mutexb.release()
mutexa.release()
#執行緒2
class
mythread2(threading.thread):
def__init__
(self):
super().
__init__
()
defrun(self):
#執行緒2獲取b鎖
ifmutexb.acquire():
print(self.name + "
-----do2---up-----")
sleep(1)
#此時執行緒1獲取了a鎖,需要等待執行緒1釋放a鎖
ifmutexa.acquire():
print(self.name + "
-----do2---down-----")
mutexa.release()
mutexb.release()
mutexa =threading.lock()
mutexb =threading.lock()
if__name__ == '
__main__':
#執行緒1和執行緒2同時執行
t1 =mythread1()
t2 =mythread2()
t1.start()
t2.start()
避免死鎖的方法:銀行家演算法
是否採用多工處理,取決於我們的任務型別
如果是計算密集型,需要大量的cpu資源進行運算,**的執行效率至關重 要,這樣的任務一般不使用多執行緒進行,因為頻繁的任務排程會拖慢cpu的
運算。如果是io密集型,涉及到硬碟讀寫,網路讀寫等的任務,更多的時間在等待 io操作完成,這一類任務可以放到多執行緒或多程序中來進行。
單執行緒、多執行緒、多程序(一起實現同一**的時間)
#單執行緒、多執行緒、多程序的使用及不同
#簡單的求和
deffib(x):
res =0
for i in range(100000000):
res += i*x
return
res#
階乘def
fac(x):
if x < 2:
return 1
return x*fac(x-1)
#簡單的求和
defsum(x):
res =0
for i in range(50000000):
res += i*x
return
res#
函式列表
funcs =[fib, fac, sum]
n = 100
class
mythread(threading.thread):
def__init__(self, func, args, name=""
): super().
__init__
() self.name =name
self.func =func
self.args =args
self.res =0
defgetresult(self):
return
self.res
defrun(self):
print("
starting
", self.name, "
at:
", ctime())
self.res =self.func(self.args)
print(self.name, "
finished at:
", ctime())
defmain():
nfuncs =range(len(funcs))
print("
單執行緒".center(30, "*"
)) start =time()
for i in
nfuncs:
print("
start {} at: {}
".format(funcs[i].__name__
, ctime()))
start_task =time()
(funcs[i](n))
end_task =time()
print("
任務 耗時:
", end_task-start_task)
print("
{} finished at: {}
".format(funcs[i].__name__
, ctime()))
end =time()
print("
", end-start)
print("
單執行緒結束:
".center(30, "*"
))
()
print("
多執行緒".center(30, "*"
)) start =time()
threads =
for i in
nfuncs:
#乙個執行緒繫結乙個函式
t = mythread(funcs[i], n, funcs[i].__name__
)
for i in
nfuncs:
#同時啟動執行緒
threads[i].start()
for i in
nfuncs:
threads[i].join()
(threads[i].getresult())
end =time()
print("
", end-start)
print("
多執行緒結束:
".center(30, "*"
))
()
print("
多程序".center(30, "*"
)) start =time()
process_list =
for i in
nfuncs:
#乙個程序繫結乙個函式
t = process(target=funcs[i], args=(n, ))
for i in
nfuncs:
#同時啟動程序
process_list[i].start()
for i in
nfuncs:
process_list[i].join()
end =time()
print("
", end -start)
print("
多程序結束:
".center(30, "*"
))if
__name__ == "
__main__":
main()
python程式設計高階
1 開閉原則 遵循開發封閉原則,雖然在這個原則是用的物件導向開發,但是也適用於函式式程式設計,簡單來說,它規定已經實現的功能 不允許被修改,但可以被擴充套件,即 封閉 已實現的功能 塊 開放 對擴充套件開發 2 可使用裝飾器實現開閉原則 裝飾器是不對原函式內部 進行修改的前提下,在外部增加一些功能,...
python高階程式設計
包和模組的概念及is和 的區別1.包 包含多個python檔案 模組的資料夾,並且資料夾中有乙個名稱為init.py的特殊宣告檔案,那麼這個資料夾就是乙個包 模組包 可以將大量功能相關的python模組包含起來統一管理,同樣也可以被其他模組通過import關鍵字引入重複使用封裝的模組和 2.模組 p...
Python高階程式設計
list comprehension 1.列表推導 i for i in range 10 if i 2 0 0,2,4,6,8 i也可以是乙個函式,該風格比c語言思想的 風格效率高 2.enumerate 取到了序列中的序列號好內容 forindex,item inenumerate sequen...