1. 程式人生 > >python核心編程筆記----threading

python核心編程筆記----threading

get rom ctime 標準 () 覆寫 pri 退出 環境

一個進程中的各個線程之間共享同一片數據空間,所以線程之間可以比進程之間更方便地共享數據以及相互通訊。

1.全局解釋器鎖(GIL)

Python 解釋器中可以“運行”多個線程,但在任意時刻,只有一個線程在解釋器中運行.
在多線程環境中,Python 虛擬機(解釋器)按以下方式執行:
1).設置 GIL
2).切換到一個線程去運行
3).運行:
a. 指定數量的字節碼指令,或者
b. 線程主動讓出控制(可以調用 time.sleep(0))
4).把線程設置為睡眠狀態
5).解鎖 GIL
6).再次重復以上所有步驟

2.退出線程

當一個線程結束計算,它就退出了。線程可以調用 thread.exit()之類的退出函數,也可以使用Python 退出進程的標準方法,如 sys.exit()或拋出一個 SystemExit 異常等。不過,你不可以直接“殺掉”("kill")一個線程。

3.Python 的線程模塊

thread 和threading 模塊允許程序員創建和管理線程。
thread 模塊提供了基本的線程和鎖的支持,而 threading提供了更高級別,功能更強的線程管理的功能。
Queue 模塊允許用戶創建一個可以用於多個線程之間共享數據的隊列數據結構。

4.threading 模塊

threading 模塊對象              描述
Thread                表示一個線程的執行的對象
Lock                  鎖原語對象(跟 thread 模塊裏的鎖對象相同)
RLock                 可重入鎖對象。使單線程可以再次獲得已經獲得了的鎖(遞歸鎖定)。
Condition               條件變量對象能讓一個線程停下來,等待其它線程滿足了某個“條件”。如,狀態的改變或值的改變。
Event                通用的條件變量。多個線程可以等待某個事件的發生,在事件發生後,所有的線程都會被激活。
Semaphore              為等待鎖的線程提供一個類似“等候室”的結構
BoundedSemaphore          與 Semaphore 類似,只是它不允許超過初始值
Timer       與Thread 相似,只是,它要等待一段時間後才開始運行

threading中的 Thread類是主要的運行對象

函數
描述
start() 開始線程的執行
run() 定義線程的功能的函數(一般會被子類重寫)
join(timeout=None) 程序掛起,直到線程結束;如果給了 timeout,則最多阻塞 timeout 秒
getName() 返回線程的名字
setName(name) 設置線程的名字
isAlive() 布爾標誌,表示這個線程是否還在運行中
isDaemon() 返回線程的 daemon 標誌(守護線程標誌)
setDaemon(daemonic) 把線程的 daemon 標誌設為 daemonic(一定要在調用 start()函數前調用)

 1 import threading
 2 from time import sleep, ctime
 3 
 4 loopn=[2,4]
 5 
 6 
 7 def loop(nloop,nsec):
 8     print "loop "+str(nloop)+" start at: "+ctime()
 9     sleep(nsec)
10     print "loop "+str(nloop)+" stop at: "+ctime()
11 
12     
13 def main():
14     print "start at "+ctime()
15     thread=[]
16     for i in range(len(loopn)):
17         t=threading.Thread(target=loop,args=(i,loopn[i]))
18         thread.append(t)
19         #start,join 在這裏執行時執行的線程運行直到結束後才開始第二個線程。
20     for i in range(len(loopn)):
21         thread[i].start()
22         
23     for i in range(len(loopn)):
24         thread[i].join()   #如果你的主線程除了等線程結束外,還有其它的事情要做(如處理或等待其它的客戶請求),那就不用調用 join(),只有在你要等待線程結束的時候才要調用 join()
25     print "stop at "+ctime()
26     
27     
28     
29 if __name__ == __main__:
30     main()

eg:所有的線程都創建了之後,再一起調用 start()函數啟動,而不是創建一個啟動一個。

join()的作用:

一旦線程啟動後,就會一直運行,直到線程的函數結束,退出為止。防止在主線程結束時 子線程還沒執行完就結束


5.生產者-消費者問題和 Queue 模塊


函數                      描述
Queue 模塊函數
queue(size) 創建一個大小為 size 的 Queue 對象
Queue 對象函數
qsize() 返回隊列的大小(由於在返回的時候,隊列可能會被其它線程修改,所以這個值是近似值)
empty() 如果隊列為空返回 True,否則返回 False
full() 如果隊列已滿返回 True,否則返回 False
put(item,block=0) 把 item 放到隊列中,如果給了 block(不為 0),函數會一直阻塞到隊列中有空間為止
get(block=0) 從隊列中取一個對象,如果給了 block(不為 0),函數會一直阻塞到隊列中有對象為止

import threading
from Queue import Queue
from time import sleep,ctime
import random


class MyThread(threading.Thread):  #threading另一種用法:繼承threading.Thread類,覆寫run函數
    def __init__(self,func,args,name=‘‘):
        threading.Thread.__init__(self)
        self.name=name
        self.func=func
        self.args=args
        
    def run(self):
        print "start "+self.name+" at;"+ctime()
        apply(self.func,self.args)
        print "stop "+self.name+" at;"+ctime()
    
def writeQ(queue):
    queue.put("item",1)
    print "product object for Q. now size: ",queue.qsize()
    
def readQ(queue):
    queue.get(1)
    print "consumed object from Q. now size:",queue.qsize()
    
def writer(queue,n):
    for i in range(n):
        writeQ(queue)
        sleep(random.randint(1,3))
        
def reader(queue,n):
    for i in range(n):
        readQ(queue)
        sleep(random.randint(3,5))
        
        
funcs=[writer,reader]
nfuncs=len(funcs)

def main():
    queue=Queue(15)
    n=random.randint(4,7)
    thread=[]
    
    for i in range(nfuncs):
        t=MyThread(funcs[i],args=(queue,n),name=funcs[i].__name__)
        thread.append(t)
        
    for i in range(nfuncs):
        thread[i].start()
        
    for i in range(nfuncs):
        thread[i].join()
        
    print "ALL DONE"
if __name__ == __main__:
    main()

運行結果:

start writer at;Tue Jun 13 21:58:23 2017
 start reader at;Tue Jun 13 21:58:23 2017
product object for Q. now size: 0
 consumed object from Q. now size:1
 
product object for Q. now size:  1
consumed object from Q. now size: 0
product object for Q. now size:  1
product object for Q. now size:  2
product object for Q. now size:  3
consumed object from Q. now size: 2
product object for Q. now size:  3
product object for Q. now size:  4
consumed object from Q. now size: 3
stop writer at;Tue Jun 13 21:58:37 2017
consumed object from Q. now size: 2
consumed object from Q. now size: 1
consumed object from Q. now size: 0
stop reader at;Tue Jun 13 21:58:50 2017
ALL DONE

python核心編程筆記----threading