?鎖
?使用鎖:
鎖的語法
創建鎖、鎖定鎖、釋放鎖
from threading import Lock # 創建鎖 mutex = Lock() # 獲取鎖(上鎖) mutex.acquire() # 釋放鎖(解鎖) mutex.release()
在鎖定鎖的過程中acquire()方法可以接受一個blocking參數,
如果設定blocking為True,則當前線程會堵塞,直到獲取到這個鎖為止(如果沒有 指定,那么默認為True)?
如果設定blocking為False,則當前線程不會堵塞
?
上鎖和解鎖的過程(假設是多線程調度):
這個鎖一般是為共享資源服務的,即多個線程同時使用共享資源。這個鎖同一時間只能有一個線程調度,其他線程阻塞,只有當前調度的線程釋放這個鎖,阻塞的線程才能調度。
鎖的優點:
確保了某段關鍵代碼只能有一個線程從頭到尾完整的執行。
鎖的缺點:
組織了多線程的并發執行,包含鎖的某段代碼實際上只能以單線程模式執行,效率就大大的降低了;代碼中可能存在多個鎖,如果多個線程擁有多個鎖,容易造成死鎖。
死鎖的現象(實例):
# 死鎖 兩者都沒有釋放對方需要的鎖,而釋放的條件恰好是獲取對方釋放所需要的鎖 # 線程1 class MyThread1(threading.Thread): def __init__ (self): super(). __init__ () def run(self): # 線程1獲取A鎖 if mutexA.acquire(): print (self.name+ " -----do1---up----- " ) sleep( 1 ) # 此時線程2獲取了B鎖,需要等待線程2釋放B鎖 if mutexB.acquire(): print (self.name + " -----do1---down----- " ) mutexB.release() mutexA.release() # 線程2 class MyThread2(threading.Thread): def __init__ (self): super(). __init__ () def run(self): # 線程2獲取B鎖 if mutexB.acquire(): print (self.name + " -----do2---up----- " ) sleep( 1 ) # 此時線程1獲取了A鎖,需要等待線程1釋放A鎖 if mutexA.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操作完成,這一類任務可以放到多線程或多進程中來進行。
單線程、多線程、多進程(一起實現同一代碼的時間)
# 單線程、多線程、多進程的使用及不同 # 簡單的求和 def fib(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 ) # 簡單的求和 def sum(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 def getResult(self): return self.res def run(self): print ( " starting " , self.name, " at: " , ctime()) self.res = self.func(self.args) print (self.name, " finished at: " , ctime()) def main(): nfuncs = range(len(funcs)) print ( " 單線程 " .center(30, " * " )) start = time() for i in nfuncs: print ( " start {} at: {} " .format(funcs[i]. __name__ , ctime())) start_task = time() print (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 () print ( " 多線程 " .center(30, " * " )) start = time() threads = [] for i in nfuncs: # 一個線程綁定一個函數 t = MyThread(funcs[i], n, funcs[i]. __name__ ) threads.append(t) for i in nfuncs: # 同時啟動線程 threads[i].start() for i in nfuncs: threads[i].join() print (threads[i].getResult()) end = time() print ( " 多線程運行時間: " , end- start) print ( " 多線程結束: " .center(30, " * " )) print () print ( " 多進程 " .center(30, " * " )) start = time() process_list = [] for i in nfuncs: # 一個進程綁定一個函數 t = Process(target=funcs[i], args= (n, )) process_list.append(t) 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()
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
