Python模組學習 —- thread 多執行緒

來源:互聯網
上載者:User

  這段時間一直在用
Python
寫一個遊戲的伺服器程式。在編寫過程中,不可避免的要用多線程來處理與用戶端的互動。
Python
標準庫提供了
thread

threading
兩個模組來對多線程進行支援。其中,
thread
模組以低級、原始的方式來處理和控制線程,而
threading
模組通過對
thread
進行二次封裝,提供了更方便的
api
來處理線程。
雖然使用
thread
沒有
threading
來的方便,但它更靈活。今天先介紹
thread
模組的基本使用,下一篇
將介紹
threading
模組。

  在介紹
thread
之前,先看一段代碼,猜猜程式運行完成之後,在控制台上輸出的結果是什嗎?

#coding=gbk<br />import thread, time, random<br />count = 0<br />def threadTest():<br /> global count<br /> for i in xrange(10000):<br /> count += 1<br />for i in range(10):<br /> thread.start_new_thread(threadTest, ())#如果對start_new_thread函數不是很瞭解,不要著急,馬上就會講解<br />time.sleep(3)<br />print count#count是多少呢?是10000 * 10 嗎?<br />

thread.start_new_thread

(
function

, args
[
, kwargs
]

)

  函數將建立一個新的線程,並返回該線程的標識符(標識符為整數)。參數
function
表示線程建立之後,立即執行的函數,參數
args
是該函數的參數,它是一個元群組類型;第二個參數
kwargs
是可選的,它為函數提供了具名引數字典。函數執行完畢之後,線程將自動結束。如果函數在執行過程中遇到未處理的異常,該線程將退出,但不會影響其他線程的執行。
下面是一個簡單的例子:

#coding=gbk<br />import thread, time<br />def threadFunc(a = None, b = None, c = None, d = None):<br /> print time.strftime('%H:%M:%S', time.localtime()), a<br /> time.sleep(1)<br /> print time.strftime('%H:%M:%S', time.localtime()), b<br /> time.sleep(1)<br /> print time.strftime('%H:%M:%S', time.localtime()), c<br /> time.sleep(1)<br /> print time.strftime('%H:%M:%S', time.localtime()), d<br /> time.sleep(1)<br /> print time.strftime('%H:%M:%S', time.localtime()), 'over'</p><p>thread.start_new_thread(threadFunc, (3, 4, 5, 6))#建立線程,並執行threadFunc函數。<br />time.sleep(5)<br />

thread.exit
()

  結束當前線程。調用該函數會觸發
SystemExit
異常,如果沒有處理該異常,線程將結束。
  

thread.get_ident
()

  返回當前線程的標識符,標識符是一個非零整數。

thread.interrupt_main
()

  在主線程中觸發
KeyboardInterrupt


異常。子線程可以使用該方法來中斷主線程。下面的例子示範了在子線程中調用
interrupt_main
,在主線程中捕獲異常
:

import thread, time<br />thread.start_new_thread(lambda : (thread.interrupt_main(), ), ())<br />try:<br /> time.sleep(2)<br />except KeyboardInterrupt, e:<br /> print 'error:', e<br />print 'over'<br />

 

  下面介紹
thread
模組中的瑣,瑣可以保證在任何時刻,最多隻有一個線程可以訪問共用資源。

thread.LockType



thread
模組中定義的瑣類型。它有如下方法:

lock.acquire
(
[

waitflag
]

)

  擷取瑣。函數返回一個布爾值,如果擷取成功,返回
True
,否則返回
False
。參數
waitflag

的預設值是一個非零整數,表示如果瑣已經被其他線程佔用,那麼當前線程將一直等待,只到其他線程釋放,然後擷取訪瑣。如果將參數
waitflag
置為
0
,那麼當前線程會嘗試擷取瑣,不管瑣是否被其他線程佔用,當前線程都不會等待。

lock.release
()

  釋放所佔用的瑣。

lock.locked
()

  判斷瑣是否被佔用。

  現在我們回過頭來看文章開始處給出的那段代碼:代碼中定義了一個函數
threadTest
,它將全域變數逐一的增加
10000
,然後在主線程中開啟了
10
個子線程來調用
threadTest
函數。但結果並不是預料中的
10000 * 10
,原因主要是對
count
的並行作業引來的。全域變數
count
是共用資源,對它的操作應該串列的進行。下面對那段代碼進行修改,在對
count
操作的時候,進行加瑣處理。看看程式啟動並執行結果是否和預期一致。修改後的代碼:

#coding=gbk<br />import thread, time, random<br />count = 0<br />lock = thread.allocate_lock() #建立一個瑣對象<br />def threadTest():<br /> global count, lock<br /> lock.acquire() #擷取瑣</p><p> for i in xrange(10000):<br /> count += 1</p><p> lock.release() #釋放瑣<br />for i in xrange(10):<br /> thread.start_new_thread(threadTest, ())<br />time.sleep(3)<br />print count<br />

  thread模組是不是並沒有想像中的那麼難!簡單就是美,這就是Python。更多關於thread模組的內容,請參考Python手冊 thread

 模組

 

 


 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.