posts - 431,  comments - 344,  trackbacks - 0
          公告
           Don't Repeat Yourself
          座右銘:you can lose your money, you can spent all of it, and if you work hard you get it all back. But if you waste your time, you're never gonna get it back.
          公告本博客在此聲明部分文章為轉摘,只做資料收集使用。


          微信: szhourui
          QQ:109450684
          Email
          lsi.zhourui@gmail.com
          <2007年9月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          30123456

          留言簿(15)

          隨筆分類(1019)

          文章分類(3)

          文章檔案(21)

          收藏夾

          Link

          好友博客

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 863934
          • 排名 - 44

          最新評論

          閱讀排行榜

          多個執行線程經常要共享數據,如果僅僅讀取共享數據還好,但是如果多個線程要修改共享數據的話就可能出現無法預料的結果。

              假如兩個線程對象t1t2都要對數值num=0進行增1運算,那么t1t2都各對num修改10次的話,那么num最終的結果應該為20。但是如果當t1取得num的值時(假如此時num0),系統把t1調度為“sleeping”狀態,而此時t2轉換為“running”狀態,此時t2獲得的num的值也為0,然后他把num+1的值1賦給num。系統又把t2轉化為“sleeping”狀態,t1為“running”狀態,由于t1已經得到num值為0,所以他也把num+1的值賦給了num1。本來是2次增1運行,結果卻是num只增了1次。類似這樣的情況在多線程同時執行的時候是有可能發生的。所以為了防止這類情況的出現就要使用線程同步機制。

              最簡單的同步機制就是“鎖”

              鎖對象用threading.RLock類創建

              mylock = threading.RLock()

              如何使用鎖來同步線程呢?線程可以使用鎖的acquire() (獲得)方法,這樣鎖就進入“locked”狀態。每次只有一個線程可以獲得鎖。如果當另一個線程試圖獲得這個鎖的時候,就會被系統變為“blocked”狀態,直到那個擁有鎖的線程調用鎖的release() (釋放)方法,這樣鎖就會進入“unlocked”狀態。“blocked”狀態的線程就會收到一個通知,并有權利獲得鎖。如果多個線程處于“blocked”狀態,所有線程都會先解除“blocked”狀態,然后系統選擇一個線程來獲得鎖,其他的線程繼續沉默(“blocked”)。

          import threading
          mylock = threading.RLock()
          class mythread(threading.Thread)
              ...
              def run(self ...):
                  ...     #此處 不可以 放置修改共享數據的代碼
                  mylock.acquire()
                  ...     #此處 可以 放置修改共享數據的代碼
                  mylock.release()
                  ...    
          #此處 不可以 放置修改共享數據的代碼

              我們把修改共享數據的代碼稱為“臨界區”,必須將所有“臨界區”都封閉在同一鎖對象的acquire()release()方法調用之間。

              鎖只能提供最基本的同步級別。有時需要更復雜的線程同步,例如只在發生某些事件時才訪問一個臨界區(例如當某個數值改變時)。這就要使用“條件變量”。

              條件變量用threading.Condition類創建

              mycondition = threading.Condition()

              條件變量是如何工作的呢?首先一個線程成功獲得一個條件變量后,調用此條件變量的wait()方法會導致這個線程釋放這個鎖,并進入“blocked”狀態,直到另一個線程調用同一個條件變量的notify()方法來喚醒那個進入“blocked”狀態的線程。如果調用這個條件變量的notifyAll()方法的話就會喚醒所有的在等待的線程。

              如果程序或者線程永遠處于“blocked”狀態的話,就會發生死鎖。所以如果使用了鎖、條件變量等同步機制的話,一定要注意仔細檢查,防止死鎖情況的發生。對于可能產生異常的臨界區要使用異常處理機制中的finally子句來保證釋放鎖。等待一個條件變量的線程必須用notify()方法顯式的喚醒,否則就永遠沉默。保證每一個wait()方法調用都有一個相對應的notify()調用,當然也可以調用notifyAll()方法以防萬一。

          posted on 2007-09-25 16:02 周銳 閱讀(1012) 評論(0)  編輯  收藏 所屬分類: Python
          主站蜘蛛池模板: 盈江县| 营口市| 石阡县| 衡水市| 绥江县| 永仁县| 武乡县| 连城县| 阿拉善盟| 黄浦区| 邓州市| 怀化市| 佛坪县| 高要市| 英德市| 博白县| 黎川县| 穆棱市| 鄄城县| 奈曼旗| 南华县| 怀远县| 大理市| 安图县| 广宁县| 霸州市| 隆回县| 安西县| 万年县| 安顺市| 海淀区| 章丘市| 蒲江县| 太仓市| 古田县| 云和县| 开封市| 乐陵市| 什邡市| 隆回县| 临海市|