天天看點

python threading 學習筆記

1.join()方法的使用

join方法,如果一個線程或者一個函數在執行過程中要調用另外一個線程,并且待到其完成以後才能接着執行,那麼在調用這個線程時可以使用被調用線程的join方法

例子:

import threading, time

class MyThread(threading.Thread):

    def __init__(self, id):

        threading.Thread.__init__(self)

        self.id = id

    def run(self):

        time.sleep(5)

        print self.id

t = MyThread(1)

def func():

    t.start()

    #t.join()

    print t.isAlive()

print func()

輸出結果

True(線程運作)

none

然後等待5秒以後輸出1

如果去掉#t.join井号的話

輸出1

False(線程退出)

2. 給線程設定名字

import threading

    def __init__(self, threadname):

        threading.Thread.__init__(self, name=threadname)

        print self.getName()

t1 = MyThread('t1')

print t1.getName()

print id(t1)

t2 = MyThread('t2')

t2.start() #注意這裡

t2.getName()

t2.setName('TT')

print id(t2)

3.守護程序

setDaemon()

這個方法基本和join是相反的。當我們在程式運作中,執行一個主線程,如果主線程又建立一個子線程,主線程和子線程就分兵兩路,分别運作,那麼當主線程完成想退出時,會檢驗子線程是否完成。如果子線程未完成,則主線程會等待子線程完成後再退出。但是有時候我們需要的是,隻要主線程完成了,不管子線程是否完成,都要和主線程一起退出,這時就可以用setDaemon方法啦

程式如下:

下面的例子就是設定子線程随主線程的結束而結束:

import time

class myThread(threading.Thread):

    def __init__(self,threadname):

        threading.Thread.__init__(self,name=threadname)

def fun1():

    t1.start()

    print 'fun1 done'

def fun2():

    t2.start()

    print 'fun2 done'

t1=myThread('t1')

t2=myThread('t2')

t2.setDaemon(True)

fun1()

fun2()

上面這個例子,按照我們設想的輸出時:

fun1 done

fun2 done

 t1

但是實際上我們在互動模式,主線程隻有在python退出時終止,是以結果t2也是被列印出來啦。

4.建立線程方法

如果你要建立一個線程對象,很簡單,隻要你的類繼承threading.Thread,然後在__init__裡首先調用threading.Thread的__init__方法即可:

  這才僅僅是個空線程,我可不是要他拉空車的,他可得給我幹點實在活。很簡單,重寫類的run()方法即可,把你要線上程執行時做的事情都放到裡面

以上代碼我們讓這個線程在執行之後每隔1秒輸出一次資訊到螢幕,10次後結束getName()是threading.Thread類的一個方法,用來獲得這個線程對象的name。還有一個方法setName()當然就是來設定這個線程對象的name的了。

如果要建立一個線程,首先就要先建立一個線程對象

mythread1 = mythread('mythread 1')

         一個線程對象被建立後,他就處于“born”(誕生狀态),如何讓這個線程對象開始運作呢?隻要調用線程對象的start()方法即可:

mythread1.start()

現線上程就處于“ready”狀态或者也稱為“runnable”狀态。

         奇怪嗎?不是已經start了嗎?為什麼不稱為“running”狀态呢?其實是有原因的。因為我們的計算機一般是不具有真正并行處理能力的。我們所謂的多線程隻是把時間分成片段,然後隔一個時間段就讓一個線程執行一下,然後進入“sleeping ”狀态,然後喚醒另一個在“sleeping”的線程,如此循環runnable->sleeping->runnable... ,隻是因為計算機執行速度很快,而時間片段間隔很小,我們感受不到,以為是同時進行的。是以說一個線程在start了之後隻是處在了可以運作的狀态,他什麼時候運作還是由系統來進行排程的。

         那一個線程什麼時候會“dead”呢?一般來說當線程對象的run方法執行結束或者在執行中抛出異常的話,那麼這個線程就會結束了。系統會自動對“dead”狀态線程進行清理。

程式:

        for i in range(10):

            print self.getName(), i

            time.sleep(1)

t1.start()