新聞中心
本篇文章為大家展示了Python進(jìn)程鎖Lock的定義,代碼簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
在昆明等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站建設(shè)、網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作按需策劃,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站建設(shè),營銷型網(wǎng)站,成都外貿(mào)網(wǎng)站制作,昆明網(wǎng)站建設(shè)費(fèi)用合理。
Lock
多線程和多進(jìn)程最大的不同在于,多進(jìn)程中,同一個(gè)變量,各自有一份拷貝存在于每個(gè)進(jìn)程中,互不影響,而多線程中,所有變量都由所有線程共享,所以,任何一個(gè)變量都可以被任何一個(gè)線程修改,因此,線程之間共享數(shù)據(jù)最大的危險(xiǎn)在于多個(gè)線程同時(shí)修改一個(gè)變量,把內(nèi)容給改亂了。
來看看多個(gè)線程同時(shí)操作一個(gè)變量怎么把內(nèi)容給改亂了:
# _*_ coding:utf-8 _*_ import time, threading # 假定這是你銀行的存款 balance = 0 def change_it(n): # 先存后取,結(jié)果應(yīng)該是0 global balance balance = balance + n balance = balance - n print balance def run_thread(n): for i in range(100000): change_it(n) t1 = threading.Thread(target=run_thread, args=(5,)) t2 = threading.Thread(target=run_thread, args=(8,)) t1.start() t2.start() t1.join() t2.join() print(balance)
我們定義了一個(gè)共享變量balance,初始值為0,并且啟動兩個(gè)線程,先存后取,理論上結(jié)果應(yīng)該為0,但是,由于線程的調(diào)度是由操作系統(tǒng)決定的,當(dāng)t1、t2交替執(zhí)行時(shí),只要循環(huán)次數(shù)足夠多,balance的結(jié)果就不一定是0了。
實(shí)際執(zhí)行效果:
$ python thread_share_var.py 31 $ python thread_share_var.py 42 $ python thread_share_var.py -6 $ python thread_share_var.py 0 $ python thread_share_var.py 7 $ python thread_share_var.py 13
究其原因,是因?yàn)樾薷腷alance需要多條語句,而執(zhí)行這幾條語句時(shí),線程可能中斷,從而導(dǎo)致多個(gè)線程把同一個(gè)對象的內(nèi)容改亂了。
兩個(gè)線程同時(shí)一存一取,就可能導(dǎo)致余額不對,你肯定不希望你的銀行存款莫名其妙地變成了負(fù)數(shù),所以,我們必須確保一個(gè)線程在修改balance的時(shí)候,別的線程一定不能改。
如果我們要確保balance計(jì)算正確,就要給change_it()上一把鎖,當(dāng)某個(gè)線程開始執(zhí)行change_it()時(shí),我們說,該線程因?yàn)楂@得了鎖,因此其他線程不能同時(shí)執(zhí)行change_it(),只能等待,直到鎖被釋放后,獲得該鎖以后才能改。由于鎖只有一個(gè),無論多少線程,同一時(shí)刻最多只有一個(gè)線程持有該鎖,所以,不會造成修改的沖突。創(chuàng)建一個(gè)鎖就是通過threading.Lock()來實(shí)現(xiàn):
balance = 0 lock = threading.Lock() def run_thread(n): for i in range(100000): # 先要獲取鎖: lock.acquire() try: # 放心地改吧: change_it(n) finally: # 改完了一定要釋放鎖: lock.release()
加鎖以后實(shí)現(xiàn)的實(shí)際效果:
$ python thread_share_var.py 0 $ python thread_share_var.py 0 $ python thread_share_var.py 0
當(dāng)多個(gè)線程同時(shí)執(zhí)行l(wèi)ock.acquire()時(shí),只有一個(gè)線程能成功地獲取鎖,然后繼續(xù)執(zhí)行代碼,其他線程就繼續(xù)等待直到獲得鎖為止。
獲得鎖的線程用完后一定要釋放鎖,否則那些苦苦等待鎖的線程將永遠(yuǎn)等待下去,成為死線程。所以我們用try...finally來確保鎖一定會被釋放。
鎖的好處就是確保了某段關(guān)鍵代碼只能由一個(gè)線程從頭到尾完整地執(zhí)行,壞處當(dāng)然也很多,首先是阻止了多線程并發(fā)執(zhí)行,包含鎖的某段代碼實(shí)際上只能以單線程模式執(zhí)行,效率就大大地下降了。其次,由于可以存在多個(gè)鎖,不同的線程持有不同的鎖,并試圖獲取對方持有的鎖時(shí),可能會造成死鎖,導(dǎo)致多個(gè)線程全部掛起,既不能執(zhí)行,也無法結(jié)束,只能靠操作系統(tǒng)強(qiáng)制終止。
上述內(nèi)容就是Python進(jìn)程鎖Lock的定義,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
標(biāo)題名稱:Python進(jìn)程鎖Lock的定義
文章起源:http://fisionsoft.com.cn/article/pcpdod.html