1.目的:為了並行運行相互獨立的子任務,大幅度提高整個任務的效率(異步任務、運算密集型任務)
UserRequestThread:負責讀取用戶的輸入,可能是一個I/O信道。程序可能會創建多個線程,每個用戶一個,請求會放在隊列中。
RequestProcessor:一個負責從隊列中獲取並且處理請求的線程,為下面這種線程提供了輸出
ReplyThread:負責把給用戶的輸出取出來,如果是網絡應用程序就把結果發送出去,否則就會保存在本地文件系統或者數據庫中。
每個線程都有自己明確的任務。
2.線程有開始,順序執行和結束三個階段
3.全局解釋器鎖(GIL):對Python虛擬機的訪問由全局控制鎖來控制,正是這個鎖能保證同一時刻只有一個線程在運行,python虛擬機按照以下的方式來運行:
(1),設置GIL (2)切換一個線程去運行 (3)運行:a.指定數量的字節碼的指令或者 b.線程主動讓出控制
(4)把線程設置為休眠狀態 (5)解鎖GIL (6)重復以上
4.在python中使用線程:_thread和threading模塊以及queue模塊。其中_thread)和threading模塊允許用戶自己創建和管理線程。queue模塊允許用戶創建一個可以用於多線程之間共享數據的隊列數據結構
注意:要避免使用_thread模塊。
_thread.start_new_thread和exit
5.threading 模塊
5.1Thread類:
用Thread類,可以用多種方法來創建線程:
a.創建一個Thread的實例,傳給他一個函數
b.創建一個Thread的實例,創給它的一個科調用的類對象
c.從Thread派生出一個子類,創建一個這個子類的試驗
函數; start(),run(),join():線程掛起,getName(),setName()
isAlive(),isDaemon(),setDeamon()
用法:threading.
Thread
(
group=None,
target=None,
name=None,
args=(),
kwargs={},
*,
daemon=None
)
當所有的線程都創建后再一起調用start()函數啟動,而不是創建一個啟動一個。不用再去管理一堆鎖,只要簡單的對每個線程調用join()函數就可以了
例子:1.構建一個線程類
#-*- encoding:utf-8 -*- import threading from time import ctime class MyThread(threading.Thread): def __init__(self,func,args,name=''): threading.Thread.__init__(self) self.func=func self.args=args self.name=name def getResult(self): return self.res def run(self): print('starting',self.name,'at',ctime()) self.res=self.func(self.args[0],self.args[1]) ####此處需要修改 print(self.name,'finished at:',ctime())
1.幾種遞歸的運算
from MyThread import MyThread from time import ctime,sleep def fib(x): sleep(0.005) if x<2: return 1 else: return (fib(x-2)+fib(x-1)) def fac(x): sleep(0.1) if x<2: return 1 return (x*fac(x-1)) def sum(x): sleep(0.1) if x<2: return 1 return (x+sum(x-1)) funcs=[fib,fac,sum] n=12 def main(): nfunc=range(len(funcs)) print('*****SINGLE THREAD') for i in nfunc: print('starting',funcs[i].__name__,'at:',ctime()) print(funcs[i](n)) print(funcs[i].__name__,'finished at:',ctime()) print('******MULTIPLE THREADS') threads=[] for i in nfunc: t=MyThread(funcs[i],(n,),funcs[i].__name__) threads.append(t) for i in nfunc: threads[i].start() for i in nfunc: threads[i].join() print(threads[i].getResult()) print('All Done') if __name__=='__main__': main()
利用Queue模塊解決生產者和消費者問題
from random import randint from time import sleep from queue import Queue from MyThread import MyThread def writeQ(queue): print('producing object for Q...') queue.put('xxx',1) print('size now',queue.qsize()) def readQ(queue): val=queue.get(1) print('consumed object from Q...size now',queue.qsize()) def write(queue,loops): for i in range(loops): writeQ(queue) sleep(randint(1,3)) def reader(queue,loops): for i in range(loops): readQ(queue) sleep(randint(2,5)) funcs=[write,reader] nfunc=range(len(funcs)) def main(): nloops=randint(2,5) q=Queue(32) threads=[] for i in nfunc: t=MyThread(funcs[i],(q,nloops),funcs[i].__name__) threads.append(t) for i in nfunc: threads[i].start() for i in nfunc: threads[i].join() print('All Done') if __name__=='__main__': main()