国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python中嘗試多線程編程的一個簡明例子

2019-11-25 17:49:32
字體:
來源:轉載
供稿:網友

綜述
    多線程是程序設計中的一個重要方面,尤其是在服務器Deamon程序方面。無論何種系統,線程調度的開銷都比傳統的進程要快得多。
  Python可以方便地支持多線程。可以快速創建線程、互斥鎖、信號量等等元素,支持線程讀寫同步互斥。美中不足的是,Python的運行在Python 虛擬機上,創建的多線程可能是虛擬的線程,需要由Python虛擬機來輪詢調度,這大大降低了Python多線程的可用性。希望高版本的Python可以 解決這個問題,發揮多CPU的最大效率。
  網上有些朋友說要獲得真正多CPU的好處,有兩種方法:
  1.可以創建多個進程而不是線程,進程數和cpu一樣多。
  2.使用Jython 或 IronPython,可以得到真正的多線程。
  閑話少說,下面看看Python如何建立線程
  Python線程創建
  使用threading模塊的 Thread類
  類接口如下

復制代碼 代碼如下:
class  Thread( group=None, target=None, name=None, args=(), kwargs={})

 需要關注的參數是target和args. target 是需要子線程運行的目標函數,args是函數的參數,以tuple的形式傳遞。
  以下代碼創建一個指向函數worker 的子線程
復制代碼 代碼如下:
def worker(a_tid,a_account):
     ...
th = threading.Thread(target=worker,args=(i,acc) ) ;

啟動這個線程

復制代碼 代碼如下:
th.start()

等待線程返回
復制代碼 代碼如下:
threading.Thread.join(th)

或者th.join()
如果你可以對要處理的數據進行很好的劃分,而且線程之間無須通信,那么你可以使用:創建=》運行=》回收的方式編寫你的多線程程序。但是如果線程之間需要訪問共同的對象,則需要引入互斥鎖或者信號量對資源進行互斥訪問。
 下面講講如何創建互斥鎖
創建鎖
復制代碼 代碼如下:
g_mutex = threading.Lock()
  ....

使用鎖 
    
復制代碼 代碼如下:
for  ... :
        #鎖定,從下一句代碼到釋放前互斥訪問
        g_mutex.acquire()
        a_account.deposite(1)
        #釋放
        g_mutex.release()

最后,模擬一個公交地鐵IC卡繳車費的多線程程序
  有10個讀卡器,每個讀卡器收費器每次扣除用戶一塊錢進入總賬中,每讀卡器每天一共被刷10000000次。賬戶原有100塊。所以最后的總賬應該為10000100。先不使用互斥鎖來進行鎖定(注釋掉了鎖定代碼),看看后果如何。

import time,datetimeimport threading def worker(a_tid,a_account): global g_mutex print("Str " , a_tid, datetime.datetime.now() ) for i in range(1000000):  #g_mutex.acquire()  a_account.deposite(1)  #g_mutex.release() print("End " , a_tid , datetime.datetime.now() )  class Account: def __init__ (self, a_base ):  self.m_amount=a_base def deposite(self,a_amount):  self.m_amount+=a_amount def withdraw(self,a_amount):  self.m_amount-=a_amount  if __name__ == "__main__": global g_mutex count = 0 dstart = datetime.datetime.now() print("Main Thread Start At: ", dstart) #init thread_pool thread_pool = [] #init mutex g_mutex = threading.Lock() # init thread items acc = Account(100) for i in range(10):  th = threading.Thread(target=worker,args=(i,acc) ) ;  thread_pool.append(th)    # start threads one by one   for i in range(10):  thread_pool[i].start()   #collect all threads for i in range(10):  threading.Thread.join(thread_pool[i]) dend = datetime.datetime.now() print("count=", acc.m_amount) print("Main Thread End at: ", dend, " time span ", dend-dstart)

注意,先不用互斥鎖進行臨界段訪問控制,運行結果如下:
201547153033091.png (640×398)

從結果看到,程序確實是多線程運行的。但是由于沒有對對象Account進行互斥訪問,所以結果是錯誤的,只有3434612,比原預計少了很多。

打開鎖后:
201547153202423.png (621×393)

這次可以看到,結果正確了。運行時間比不進行互斥多了很多,不過這也是同步的代價。
同時發現,寫多線程,多進程類的程序,不能用自帶的idle來運行。會有錯誤。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 昌乐县| 介休市| 乌兰浩特市| 阜康市| 岳普湖县| 平安县| 宣武区| 兴业县| 呼伦贝尔市| 昌平区| 会东县| 盐亭县| 濮阳市| 海林市| 荆门市| 都江堰市| 尼勒克县| 沿河| 留坝县| 青海省| 玛多县| 措美县| 乐亭县| 凤山市| 海安县| 衡阳县| 普定县| 海丰县| 佛学| 鲁山县| 将乐县| 安阳县| 朝阳市| 青州市| 西青区| 焉耆| 莒南县| 宁陵县| 兴安县| 宁强县| 宕昌县|