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

資訊專欄INFORMATION COLUMN

Python并行編程多線程鎖機制Lock與RLock實現線程同步

89542767 / 486人閱讀

  Python作為一門比較常見的編程語言,可以對其進行多線程的編程,包括利用Lock與RLock,實現多線程之間的相互同步,那么,實現這種原理的機制到底是什么樣子的呢?下面就給大家詳細解答下。


  什么是鎖機制?


  要回答這個問題,我們需要知道為什么需要使用鎖機制。前面我們談到一個進程內的多個線程的某些資源是共享的,這也是線程的一大優勢,但是也隨之帶來一個問題,即當兩個及兩個以上的線程同時訪問共享資源時,如果此時沒有預設對應的同步機制,就可能帶來同一時刻多個線程同時訪問同一個共享資源,即出現競態,多數情況下我們是不希望出現這樣的情況的,那么怎么避免呢?


  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)

  運行截圖如下:

01.png

  運行結果


  當我們多次運行時,可以看到最終的結果都幾乎不等于我們期待的值即resource初始值0。


  為什么呢?原因就是因為+=和-=并不是原子操作。


  可以使用dis模塊查看字節碼:


  import dis
  def add(total):
  total+=1
  def desc(total):
  total-=1
  total=0
  print(dis.dis(add))
  print(dis.dis(desc))
  #運行結果:
  #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)


  運行截圖如下:

02.png

  運行結果


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


  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()的區別


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


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


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


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


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


  綜上所述,這篇文章就給大家介紹到這里了,希望可以給大家帶來幫助。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/128429.html

相關文章

  • 并發模型:線程

    摘要:文章結構來自七周七并發模型互斥和內存模型創建線程這段代碼創建并啟動了一個實例,首先從開始,函數的余下部分一起并發執行。在鎖定狀態下,某些線程擁有鎖在非鎖定狀態下,沒有線程擁有它。 并發&并行 并發程序含有多個邏輯上的獨立執行塊,他們可以獨立的并行執行,也可以串行執行。并行程序解決問題的速度比串行程序快的多,因為其可以同時執行整個任務的多個部分。并行程序可能有多個獨立執行塊,也可能只有一...

    JasinYip 評論0 收藏0
  • python并發4:使用thread處理并發

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

    joywek 評論0 收藏0
  • python---線程

    摘要:某進程內的線程在其它進程不可見。線程的實體包括程序數據和。包括以下信息線程狀態。當線程不運行時,被保存的現場資源。用戶級線程執行系統調用指令時將導致其所屬進程被中斷,而內核支持線程執行系統調用指令時,只導致該線程被中斷。線程能夠利用的表空 操作系統線程理論 線程概念的引入背景 進程之前我們已經了解了操作系統中進程的概念,程序并不能單獨運行,只有將程序裝載到內存中,系統為它分配資源才能運...

    Yangyang 評論0 收藏0
  • Python 的并發編程

    摘要:本文最先發布在博客這篇文章將講解并發編程的基本操作。并發是指能夠多任務處理,并行則是是能夠同時多任務處理。雖然自帶了很好的類庫支持多線程進程編程,但眾所周知,因為的存在,很難做好真正的并行。 本文最先發布在博客:https://blog.ihypo.net/151628... 這篇文章將講解 Python 并發編程的基本操作。并發和并行是對孿生兄弟,概念經常混淆。并發是指能夠多任務處...

    happen 評論0 收藏0
  • python線程

    摘要:對于操作為主的編程來說,多進程和多先產出的性能差別不大,甚至多線程比多進程的性能還高,因為多線程編程更加輕量級。 GIL global interpreter lock(cpython) 同一時刻只有一個線程運行在一個cpu上執行字節碼(無法將多個線程映射到多個cpu上) import dis def add(a): a = a + 1 return a print...

    J4ck_Chan 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<