天天看點

【python标準庫學習】thread,threading(一)多線程的介紹和使用

        在單個程式中我們經常用多線程來處理不同的工作,尤其是有的工作需要等,那麼我們會建立一個線程去等然後執行某些操作,當做完事後線程退出被回收。當一個程式運作時,就會有一個程序被系統所建立,同時也會有一個線程運作,這個線程就是主線程main,在主線程中所建立的新的線程都是子線程,子線程通常都是做一些輔助的事。python中提供了thread和threading兩個子產品來支援多線程。

        python中使用線程有兩種方式,第一種是用thread子產品的start_new_thread函數,另一種是用threading子產品的Thread類來包裝線程對象。

1.使用thread子產品

        使用thread子產品的start_new_thread函數建立線程并啟動。start_new_thread函數原型:

        thread.start_new_thread(function, args[, kwargs])

        這個函數建立一個新線程,并立刻執行函數function,args是該函數function的參數,是一個元組,kwargs是可選的,它為函數提供了命名參數字典。該函數傳回一個整數,為線程标示符。function函數執行完後線程正常退出,如果執行過程中有未處理的異常,線程會異常退出。

        thread子產品的主要函數:

        1).start_new_thread()

           建立并啟動線程執行function函數,function執行完線程退出,或者遇到未處理的異常線程異常退出。

        2).thread.exit()

           結束目前線程,會觸發SystemExit異常,如果沒有捕獲處理該異常,線程會退出。

        3).thread.get_ident()

           得到該線程的标示符,就是建立線程時傳回的标示符,是一個整數。

        4).thread.interrupt_main

           在主線程main中觸發一個KeyboardInterrupt異常,子線程用這個函數來終止主線程。

        5).thread.allocate_lock()

           建立一個鎖對象LockType,使多個線程同步通路共享資源。

        在python中使用多線程更多的是使用第二種方式,即使用threading子產品。

2.使用threading子產品

        threading子產品是對thread子產品的第二次封裝,提供了更好的API來讓我們使用。使用threading實作多線程程式設計都是使用的Thread類,或者Timer類,Timer是Thread的子類,可以指定時間間隔後在執行某個操作:

        使用Thread類有兩種方式,一種是直接建立Thread類的執行個體,另一種方式是自定義類來繼承Thread類。使用Thread類的執行個體,在它的初始化函數__init__中将可調用的對象作為參數傳入,Thread的初始化函數__init__原型:

        __init__(self, group=None, target=None, name=None, args=(), kwargs=None, verbose=None);

group和verbose不知道是什麼東西,target是可調用對象,線程啟動後就執行它,name為線程的名字,預設為"Thread-N",N為數字,args和kwargs是調用target是的參數清單和關鍵字參數。

        自定義類來繼承Thread類,然後重寫run方法實作我們自己的操作。

        邏輯代碼是寫在run方法中的,但是我們啟動線程都是用的start方法,這兩個方法是有差別的,如果直接調用run()方法,隻是單純的調用方法,而調用start()方法是将線程從建立狀态啟動程式設計就緒狀态,等待cpu的排程,這裡涉及到線程的幾種狀态,start()後線程沒有立即運作而是程式設計就緒狀态,當得到cpu時間片後程式設計運作狀态,當run方法結束或者有未處理的異常,線程就結束變成死亡狀态等待被回收,在運作狀态如果遇到資源沒有準備好就會變成阻塞狀态,當得到資源後再次程式設計就緒狀态等待cpu的排程。

        threading子產品的主要類:

        1).Thread類

           上面已經介紹。

        2).Timer類

           Thread的子類,上面已經介紹。

        3).Lock,RLock,Condition類

           同步鎖,用于多實作線程同步,資源共享的問題。

        4).Event類

           用于多線程通信。

        多線程同步鎖Lock,RLock,Condition和多線程通信Event後面在多線程同步再介紹。

        threading子產品Thread類的主要函數:

        1).Thread.getName(),Thread.setName()

           擷取和設定線程名字。

        2).Thread.ident()

           擷取線程的标示符,是一個整數。

        3).Thread.is_alive(),Thread.isAlive()

           判斷線程是不是活的,即線程是否已經結束。

        4).Thread.activeCount()

           擷取目前活着的所有線程總數,包括主線程main。

        5).Thread.join()

           使主線程阻塞,知道該子線程執行完或者逾時,它有一個參數timeout表示逾時時間,預設為None。

        6).Thread.setDaemon()

           有一個布爾值的參數,預設為False,該方法設定子線程是否随主線程一起結束。

        看看join方法和setDaemon方法:

        輸出結果:

        主線程中sleep(1)一秒就是為了讓線程被排程,線程中sleep(3)三秒就是為了讓主線程結束,從兩種情況的輸出結果可以看出join的功能。

        從列印的結果可以看出,當設定為True的時候,線程還在sleep過程就就結束了,以至于thread end這句都沒有列印出來。

        當然Thread類還不止這些方法,這些隻是常用的方法,通過help(Thread)可以檢視。