国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

Python并行編程多線程鎖機(jī)制Lock與RLock實(shí)現(xiàn)線程同步

89542767 / 499人閱讀

  Python作為一門(mén)比較常見(jiàn)的編程語(yǔ)言,可以對(duì)其進(jìn)行多線程的編程,包括利用Lock與RLock,實(shí)現(xiàn)多線程之間的相互同步,那么,實(shí)現(xiàn)這種原理的機(jī)制到底是什么樣子的呢?下面就給大家詳細(xì)解答下。


  什么是鎖機(jī)制?


  要回答這個(gè)問(wèn)題,我們需要知道為什么需要使用鎖機(jī)制。前面我們談到一個(gè)進(jìn)程內(nèi)的多個(gè)線程的某些資源是共享的,這也是線程的一大優(yōu)勢(shì),但是也隨之帶來(lái)一個(gè)問(wèn)題,即當(dāng)兩個(gè)及兩個(gè)以上的線程同時(shí)訪問(wèn)共享資源時(shí),如果此時(shí)沒(méi)有預(yù)設(shè)對(duì)應(yīng)的同步機(jī)制,就可能帶來(lái)同一時(shí)刻多個(gè)線程同時(shí)訪問(wèn)同一個(gè)共享資源,即出現(xiàn)競(jìng)態(tài),多數(shù)情況下我們是不希望出現(xiàn)這樣的情況的,那么怎么避免呢?


  Lock()管理線程


  先看一段代碼:


  import threading
  import time
  resource=0
  count=1000000
  resource_lock=threading.Lock()
  def increment():
  global resource
  for i in range(count):
  resource+=1
  def decerment():
  global resource
  for i in range(count):
  resource-=1
  increment_thread=threading.Thread(target=increment)
  decerment_thread=threading.Thread(target=decerment)
  increment_thread.start()
  decerment_thread.start()
  increment_thread.join()
  decerment_thread.join()
  print(resource)

  運(yùn)行截圖如下:

01.png

  運(yùn)行結(jié)果


  當(dāng)我們多次運(yùn)行時(shí),可以看到最終的結(jié)果都幾乎不等于我們期待的值即resource初始值0。


  為什么呢?原因就是因?yàn)?=和-=并不是原子操作。


  可以使用dis模塊查看字節(jié)碼:


  import dis
  def add(total):
  total+=1
  def desc(total):
  total-=1
  total=0
  print(dis.dis(add))
  print(dis.dis(desc))
  #運(yùn)行結(jié)果:
  #3 0 LOAD_FAST 0(total)
  #3 LOAD_CONST 1(1)
  #6 INPLACE_ADD
  #7 STORE_FAST 0(total)
  #10 LOAD_CONST 0(None)
  #13 RETURN_VALUE
  #None
  #5 0 LOAD_FAST 0(total)
  #3 LOAD_CONST 1(1)
  #6 INPLACE_SUBTRACT
  #7 STORE_FAST 0(total)
  #10 LOAD_CONST 0(None)
  #13 RETURN_VALUE
  #None

  那么如何保證初始值為0呢?我們可以利用Lock(),代碼如下:


  import threading
  import time
  resource=0
  count=1000000
  resource_lock=threading.Lock()
  def increment():
  global resource
  for i in range(count):
  resource_lock.acquire()
  resource+=1
  resource_lock.release()
  def decerment():
  global resource
  for i in range(count):
  resource_lock.acquire()
  resource-=1
  resource_lock.release()
  increment_thread=threading.Thread(target=increment)
  decerment_thread=threading.Thread(target=decerment)
  increment_thread.start()
  decerment_thread.start()
  increment_thread.join()
  decerment_thread.join()
  print(resource)


  運(yùn)行截圖如下:

02.png

  運(yùn)行結(jié)果


  從運(yùn)行結(jié)果可以看到,不論我們運(yùn)行多少次改代碼,其resource的值都為初始值0,這就是Lock()的功勞,即它可以將某一時(shí)刻的訪問(wèn)限定在單個(gè)線程或者單個(gè)類(lèi)型的線程上,在訪問(wèn)鎖定的共享資源時(shí),必須要現(xiàn)獲取對(duì)應(yīng)的鎖才能訪問(wèn),即要等待其他線程釋放資源,即resource_lock.release()當(dāng)然為了防止我們對(duì)某個(gè)資源鎖定后,忘記釋放鎖,導(dǎo)致死鎖,我們可以利用上下文管理器管理鎖實(shí)現(xiàn)同樣的效果:


  import threading
  import time
  resource=0
  count=1000000
  resource_lock=threading.Lock()
  def increment():
  global resource
  for i in range(count):
  with resource_lock:
  resource+=1
  def decerment():
  global resource
  for i in range(count):
  with resource_lock:
  resource-=1
  increment_thread=threading.Thread(target=increment)
  decerment_thread=threading.Thread(target=decerment)
  increment_thread.start()
  decerment_thread.start()


  RLock()與Lock()的區(qū)別


  我們需要知道Lock()作為一個(gè)基本的鎖對(duì)象,一次只能一個(gè)鎖定,其余鎖請(qǐng)求,需等待鎖釋放后才能獲取,否則會(huì)發(fā)生死鎖:


  import threading
  resource.lock=threading.lock()
  resource=0
  resource.lock.acquire()
  resource.lock.acquire()
  resource+=1
  resource.lock.release()
  resource.lock.release()


  為解決同一線程中不能多次請(qǐng)求同一資源的問(wèn)題,python提供了“可重入鎖”:threading.RLock,RLock內(nèi)部維護(hù)著一個(gè)Lock和一個(gè)counter變量,counter記錄了acquire的次數(shù),從而使得資源可以被多次acquire。


  直到一個(gè)線程所有的acquire都被release,其他的線程才能獲得資源。用法和threading.Lock類(lèi)相同,即比如遞歸鎖的使用:


  import threading
  lock=threading.RLock()
  def dosomething(lock):
  lock.acquire()
  #do something
  lock.release()
  lock.acquire()
  dosomething(lock)
  lock.release()


  綜上所述,這篇文章就給大家介紹到這里了,希望可以給大家?guī)?lái)幫助。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/128429.html

相關(guān)文章

  • 并發(fā)模型:線程

    摘要:文章結(jié)構(gòu)來(lái)自七周七并發(fā)模型互斥和內(nèi)存模型創(chuàng)建線程這段代碼創(chuàng)建并啟動(dòng)了一個(gè)實(shí)例,首先從開(kāi)始,函數(shù)的余下部分一起并發(fā)執(zhí)行。在鎖定狀態(tài)下,某些線程擁有鎖在非鎖定狀態(tài)下,沒(méi)有線程擁有它。 并發(fā)&并行 并發(fā)程序含有多個(gè)邏輯上的獨(dú)立執(zhí)行塊,他們可以獨(dú)立的并行執(zhí)行,也可以串行執(zhí)行。并行程序解決問(wèn)題的速度比串行程序快的多,因?yàn)槠淇梢酝瑫r(shí)執(zhí)行整個(gè)任務(wù)的多個(gè)部分。并行程序可能有多個(gè)獨(dú)立執(zhí)行塊,也可能只有一...

    JasinYip 評(píng)論0 收藏0
  • python并發(fā)4:使用thread處理并發(fā)

    摘要:如果某線程并未使用很多操作,它會(huì)在自己的時(shí)間片內(nèi)一直占用處理器和。在中使用線程在和等大多數(shù)類(lèi)系統(tǒng)上運(yùn)行時(shí),支持多線程編程。守護(hù)線程另一個(gè)避免使用模塊的原因是,它不支持守護(hù)線程。 這一篇是Python并發(fā)的第四篇,主要介紹進(jìn)程和線程的定義,Python線程和全局解釋器鎖以及Python如何使用thread模塊處理并發(fā) 引言&動(dòng)機(jī) 考慮一下這個(gè)場(chǎng)景,我們有10000條數(shù)據(jù)需要處理,處理每條...

    joywek 評(píng)論0 收藏0
  • python---線程

    摘要:某進(jìn)程內(nèi)的線程在其它進(jìn)程不可見(jiàn)。線程的實(shí)體包括程序數(shù)據(jù)和。包括以下信息線程狀態(tài)。當(dāng)線程不運(yùn)行時(shí),被保存的現(xiàn)場(chǎng)資源。用戶級(jí)線程執(zhí)行系統(tǒng)調(diào)用指令時(shí)將導(dǎo)致其所屬進(jìn)程被中斷,而內(nèi)核支持線程執(zhí)行系統(tǒng)調(diào)用指令時(shí),只導(dǎo)致該線程被中斷。線程能夠利用的表空 操作系統(tǒng)線程理論 線程概念的引入背景 進(jìn)程之前我們已經(jīng)了解了操作系統(tǒng)中進(jìn)程的概念,程序并不能單獨(dú)運(yùn)行,只有將程序裝載到內(nèi)存中,系統(tǒng)為它分配資源才能運(yùn)...

    Yangyang 評(píng)論0 收藏0
  • Python 的并發(fā)編程

    摘要:本文最先發(fā)布在博客這篇文章將講解并發(fā)編程的基本操作。并發(fā)是指能夠多任務(wù)處理,并行則是是能夠同時(shí)多任務(wù)處理。雖然自帶了很好的類(lèi)庫(kù)支持多線程進(jìn)程編程,但眾所周知,因?yàn)榈拇嬖冢茈y做好真正的并行。 本文最先發(fā)布在博客:https://blog.ihypo.net/151628... 這篇文章將講解 Python 并發(fā)編程的基本操作。并發(fā)和并行是對(duì)孿生兄弟,概念經(jīng)常混淆。并發(fā)是指能夠多任務(wù)處...

    happen 評(píng)論0 收藏0
  • python線程

    摘要:對(duì)于操作為主的編程來(lái)說(shuō),多進(jìn)程和多先產(chǎn)出的性能差別不大,甚至多線程比多進(jìn)程的性能還高,因?yàn)槎嗑€程編程更加輕量級(jí)。 GIL global interpreter lock(cpython) 同一時(shí)刻只有一個(gè)線程運(yùn)行在一個(gè)cpu上執(zhí)行字節(jié)碼(無(wú)法將多個(gè)線程映射到多個(gè)cpu上) import dis def add(a): a = a + 1 return a print...

    J4ck_Chan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<