多線程編程(2)
目前Python的lib中對多線程編程提供兩種啟動方法,一種是比較基本的thread模組中start_new_thread方法,線上程中運行一個函數, 另一種是使用整合threading模組的線程對象Thread類。
目前所用到的,是舊版本中調用thread模組中的start_new_thread()函數來產生新的線程
相比而言,thread.start_new_thread(function,(args[,kwargs]))實現機制其實與C更為類似,其中function參數是將要調用的線程函數;(args[,kwargs])是將傳遞給待建立線程函數的參數組成的元群組類型,其中kwargs是可選的參數。新建立的線程結束一般依靠線程函數的執行結束自動結束,或者線上程函數中調用thread.exit()拋出SystemExit exception, 達到線程退出的目的。
print "=======================thread.start_new_thread啟動線程=============" import thread #Python的線程sleep方法並不是在thread模組中,反而是在time模組下 import time def inthread(no,interval): count=0 while count<10: print "Thread-%d,休眠間隔:%d,current Time:%s"%(no,interval,time.ctime()) #使當前線程休眠指定時間,interval為浮點型的秒數,不同於Java中的整形毫秒數 time.sleep(interval) #Python不像大多數進階語言一樣支援++操作符,只能用+=實現 count+=1 else: print "Thread-%d is over"%no #可以等待線程被PVM回收,或主動調用exit或exit_thread方法結束線程 thread.exit_thread() #使用start_new_thread函數可以簡單的啟動一個線程,第一個參數指定線程中執行的函數,第二個參數為元組型的傳遞給指定函數的參數值 thread.start_new_thread(inthread,(1,2)) #線程執行時必須添加這一行,並且sleep的時間必須足夠使線程結束,如本例 #如果休眠時間改為20,將可能會拋出異常 time.sleep(30) '''
使用這種方法啟動線程時,有可能出現異常
Unhandled exception in thread started by
Error in sys.excepthook:
Original exception was:
解決:啟動線程之後,須確保主線程等待所有子線程返回結果後再退出,如果主線程比子線程早結束,無論其子線程是否是後台線程,都將會中斷,拋出這個異常
若沒有響應阻塞等待,為避免主線程提前退出,必須調用time.sleep使主線程休眠足夠長的時間,另外也可以採用加鎖機制來避免類似情況,通過在啟動線程的時候,給每個線程都加了一把鎖,直到線程運行介紹,再釋放這個鎖。同時在Python的main線程中用一個while迴圈來不停的判斷每個線程鎖已釋放。
import thread; from time import sleep,ctime; from random import choice #The first param means the thread number #The second param means how long it sleep #The third param means the Lock def loop(nloop,sec,lock): print "Thread ",nloop," start and will sleep ",sec; sleep(sec); print "Thread ",nloop," end ",sec; lock.release(); def main(): seconds=[4,2]; locks=[]; for i in range(len(seconds)) : lock=thread.allocate_lock(); lock.acquire(); locks.append(lock); print "main Thread begins:",ctime(); for i,lock in enumerate(locks): thread.start_new_thread(loop,(i,choice(seconds),lock)); for lock in locks : while lock.locked() : pass; print "main Thread ends:",ctime(); if __name__=="__main__" : main();
很多介紹說在新python版本中推薦使用Threading模組,目前暫沒有應用到。。。