Python創建線程(2種方式)詳解


Python 中,有關線程開發的部分被單獨封裝到了模塊中,和線程相關的模塊有以下 2 個:

  • _thread:是 Python 3 以前版本中 thread 模塊的重命名,此模塊僅提供了低級別的、原始的線程支持,以及一個簡單的鎖。功能比較有限。正如它的名字所暗示的(以 _ 開頭),一般不建議使用 thread 模塊;
  • threading:Python 3 之后的線程模塊,提供了功能豐富的多線程支持,推薦使用。


本節就以 threading 模塊為例進行講解。Python 主要通過兩種方式來創建線程:

  1. 使用 threading 模塊中 Thread 類的構造器創建線程。即直接對類 threading.Thread 進行實例化創建線程,並調用實例化對象的 start() 方法啟動線程。
  2. 繼承 threading 模塊中的 Thread 類創建線程類。即用 threading.Thread 派生出一個新的子類,將新建類實例化創建線程,並調用其 start() 方法啟動線程。

調用Thread類的構造器創建線程

Thread 類提供了如下的 __init__() 構造器,可以用來創建線程:

__init__(self, group=None, target=None, name=None, args=(), kwargs=None, *,daemon=None)

此構造方法中,以上所有參數都是可選參數,即可以使用,也可以忽略。其中各個參數的含義如下:

  • group:指定所創建的線程隸屬於哪個線程組(此參數尚未實現,無需調用);
  • target:指定所創建的線程要調度的目標方法(最常用);
  • args:以元組的方式,為 target 指定的方法傳遞參數;
  • kwargs:以字典的方式,為 target 指定的方法傳遞參數;
  • daemon:指定所創建的線程是否為后代線程。

這些參數,初學者只需記住 target、args、kwargs 這 3 個參數的功能即可。

下面程序演示了如何使用 Thread 類的構造方法創建一個線程:

 
        
import threading
#定義線程要調用的方法,*add可接收多個以非關鍵字方式傳入的參數
def action(*add):
    for arc in add:
        #調用 getName() 方法獲取當前執行該程序的線程名
        print(threading.current_thread().getName() +" "+ arc)
#定義為線程方法傳入的參數
my_tuple = ("http://c.biancheng.net/python/",\
            "http://c.biancheng.net/shell/",\
            "http://c.biancheng.net/java/")
#創建線程
thread = threading.Thread(target = action,args =my_tuple)
 
        

由此就創建好了一個線程。但是線程需要手動啟動才能運行,threading 模塊提供了 start() 方法用來啟動線程。因此在上面程序的基礎上,添加如下語句:

  1. thread.start()

再次執行程序,其輸出結果為:

  Thread-1 http://c.biancheng.net/python/
  Thread-1 http://c.biancheng.net/shell/
  Thread-1 http://c.biancheng.net/java/

可以看到,新創建的 thread 線程(線程名為 Thread-1)執行了 action() 函數。

默認情況下,主線程的名字為 MainThread,用戶啟動的多個線程的名字依次為 Thread-1、Thread-2、Thread-3、...、Thread-n 等。

為了使 thread 線程的作用更加明顯,可以繼續在上面程序的基礎上添加如下代碼,讓主線程和新創建線程同時工作:

  1. for i in range(5):
  2. print(threading.current_thread().getName())

再次執行程序,其輸出結果為:

  MainThreadThread-1 http://c.biancheng.net/python/

  MainThreadThread-1 http://c.biancheng.net/shell/

  MainThreadThread-1 http://c.biancheng.net/java/

  MainThread
  MainThread

可以看到,當前程序中有 2 個線程,分別為主線程 MainThread 和子線程 Thread-1,它們以並發方式執行,即 Thread-1 執行一段時間,然后 MainThread 執行一段時間。通過輪流獲得 CPU 執行一段時間的方式,程序的執行在多個線程之間切換,從而給用戶一種錯覺,即多個線程似乎同時在執行。

如果程序中不顯式創建任何線程,則所有程序的執行,都將由主線程 MainThread 完成,程序就只能按照順序依次執行。

繼承Thread類創建線程類

通過繼承 Thread 類,我們可以自定義一個線程類,從而實例化該類對象,獲得子線程。

需要注意的是,在創建 Thread 類的子類時,必須重寫從父類繼承得到的 run() 方法。因為該方法即為要創建的子線程執行的方法,其功能如同第一種創建方法中的 action() 自定義函數。

下面程序,演示了如何通過繼承 Thread 類創建並啟動一個線程:

import threading

#創建子線程類,繼承自 Thread 類
class my_Thread(threading.Thread):
    def __init__(self,add):
        threading.Thread.__init__(self)
        self.add = add
    # 重寫run()方法
    def run(self):
         for arc in self.add:
            #調用 getName() 方法獲取當前執行該程序的線程名
            print(threading.current_thread().getName() +" "+ arc)

#定義為 run() 方法傳入的參數
my_tuple = ("http://c.biancheng.net/python/",\
            "http://c.biancheng.net/shell/",\
            "http://c.biancheng.net/java/")
#創建子線程
mythread = my_Thread(my_tuple)
#啟動子線程
mythread.start()
#主線程執行此循環
for i in range(5):
    print(threading.current_thread().getName())

 

程序執行結果為:

  MainThreadThread-1 http://c.biancheng.net/python/

  MainThreadThread-1 http://c.biancheng.net/shell/

  MainThreadThread-1 http://c.biancheng.net/java/

  MainThread
  MainThread


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM