AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

Python多線程詳細體驗

來源: 責編: 時間:2023-10-08 07:06:30 228觀看
導讀線程是處理器調度和分配的基本單位,進程則作為資源擁有的基本單位。每個進程是由私有的虛擬地址空間、代碼、數據和其它各種系統資源組成。線程是進程內部的一個執行單元。每一個進程至少有一個主執行線程,它無需由用戶

線程是處理器調度和分配的基本單位,進程則作為資源擁有的基本單位。每個進程是由私有的虛擬地址空間、代碼、數據和其它各種系統資源組成。線程是進程內部的一個執行單元。每一個進程至少有一個主執行線程,它無需由用戶去主動創建,是由系統自動創建的。用戶根據需要在應用程序中創建其它線程,多個線程并發地運行于同一個進程中。x3w28資訊網——每日最新資訊28at.com

x3w28資訊網——每日最新資訊28at.com

x3w28資訊網——每日最新資訊28at.com

一、創建線程的方式-threading

方法1

在實例化一個線程對象時,將要執行的任務函數以參數的形式傳入threading:x3w28資訊網——每日最新資訊28at.com

# -*- coding: utf-8 -*-import timeimport threadingimport datetimedef printNumber(n: int) -> None:    while True:        times = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')        print(f'{times}-{n}')        time.sleep(n)for i in range(1, 3):    t = threading.Thread(target=printNumber, args=(i,))    t.start()# 輸出2022-12-16 11:04:40-12022-12-16 11:04:40-22022-12-16 11:04:41-12022-12-16 11:04:42-22022-12-16 11:04:42-12022-12-16 11:04:43-12022-12-16 11:04:44-22022-12-16 11:04:44-12022-12-16 11:04:45-12022-12-16 11:04:46-22022-12-16 11:04:46-12022-12-16 11:04:47-1....Process finished with exit code -1

創建兩個線程,一個線程每隔一秒打印一個“1”,另一個線程每隔2秒打印一個“2”Thread 類提供了如下的 init() 構造器,可以用來創建線程:x3w28資訊網——每日最新資訊28at.com

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

x3w28資訊網——每日最新資訊28at.com

此構造方法中,以上所有參數都是可選參數,即可以使用,也可以忽略。其中各個參數的含義如下:x3w28資訊網——每日最新資訊28at.com

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

這些參數,初學者只需記住 target、args、kwargs 這 3 個參數的功能即可。但是線程需要手動啟動才能運行,threading 模塊提供了 start() 方法用來啟動線程。因此在上面程序的基礎上,添加如下語句:t.start()x3w28資訊網——每日最新資訊28at.com

方法2

通過繼承 Thread 類,我們可以自定義一個線程類,從而實例化該類對象,獲得子線程。x3w28資訊網——每日最新資訊28at.com

需要注意的是,在創建 Thread 類的子類時,必須重寫從父類繼承得到的 run() 方法。因為該方法即為要創建的子線程執行的方法,其功能如同第一種創建方法中的 printNumber() 自定義函數。x3w28資訊網——每日最新資訊28at.com

# -*- coding: utf-8 -*-import datetimeimport timeimport threadingclass MyThread(threading.Thread):    def __init__(self, n):        self.n = n        # 注意:一定要調用父類的初始化函數        super().__init__()    def run(self) -> None:        while True:            times = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')            print(f'{times}-{self.n}')            time.sleep(self.n)for i in range(1, 3):    t = MyThread(i)    t.start()# 輸出2022-12-16 12:43:24-12022-12-16 12:43:24-22022-12-16 12:43:25-12022-12-16 12:43:26-22022-12-16 12:43:26-12022-12-16 12:43:27-12022-12-16 12:43:28-2...

x3w28資訊網——每日最新資訊28at.com

二、主線程和子線程

# -*- coding: utf-8 -*-import datetimeimport timeimport threadingclass MyThread(threading.Thread):    def __init__(self, n):        self.n = n        # 注意:一定要調用父類的初始化函數,否則無法創建線程        super().__init__()    def run(self) -> None:        while True:            _count = threading.active_count()            threading_name = threading.current_thread().getName()            times = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')            print(f'{times}-{self.n}-"當前活躍的線程個數:{_count}"-"當前線程的名稱是":{threading_name}')            time.sleep(self.n)for i in range(1, 3):    t = MyThread(i)    t.start()    print(threading.current_thread().getName())# 輸出2022-12-16 13:18:00-1-"當前活躍的線程個數:2"-"當前線程的名稱是":Thread-1MainThread2022-12-16 13:18:00-2-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-2MainThread2022-12-16 13:18:01-1-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-12022-12-16 13:18:02-2-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-22022-12-16 13:18:02-1-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-12022-12-16 13:18:03-1-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-12022-12-16 13:18:04-2-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-22022-12-16 13:18:04-1-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-1...

x3w28資訊網——每日最新資訊28at.com

注意: 第一次t.start()后,當前存在兩個線程(主線程+子線程),第二次t.start()的時候又創建了一個子線程所以當前存在三個線程。x3w28資訊網——每日最新資訊28at.com

如果程序中不顯式創建任何線程,則所有程序的執行,都將由主線程 MainThread 完成,程序就只能按照順序依次執行。x3w28資訊網——每日最新資訊28at.com

x3w28資訊網——每日最新資訊28at.com

此程序中,子線程 Thread-1和Thread-2 執行的是 run() 方法中的代碼,而 MainThread 執行的是主程序中的代碼,它們以快速輪換 CPU 的方式在執行。x3w28資訊網——每日最新資訊28at.com

x3w28資訊網——每日最新資訊28at.com

三、守護線程(Daemon Thread)

守護線程(Daemon Thread)也叫后臺進程,它的目的是為其他線程提供服務。如果其他線程被殺死了,那么守護線程也就沒有了存在的必要。因此守護線程會隨著非守護線程的消亡而消亡。Thread類中,子線程被創建時默認是非守護線程,我們可以通過setDaemon(True)將一個子線程設置為守護線程。x3w28資訊網——每日最新資訊28at.com

# -*- coding: utf-8 -*-import datetimeimport timeimport threadingclass MyThread(threading.Thread):    def __init__(self, n):        self.n = n        # 注意:一定要調用父類的初始化函數,否則無法創建線程        super().__init__()    def run(self) -> None:        while True:            _count = threading.active_count()            threading_name = threading.current_thread().getName()            times = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')            print(f'{times}-{self.n}-"當前活躍的線程個數:{_count}"-"當前線程的名稱是":{threading_name}')            time.sleep(self.n)for i in range(1, 3):    t = MyThread(i)    t.setDaemon(True)    t.start()    print(threading.current_thread().getName())        # 輸出2022-12-16 13:27:46-1-"當前活躍的線程個數:2"-"當前線程的名稱是":Thread-1MainThread2022-12-16 13:27:46-2-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-2MainThread

將兩個子線程改寫為守護線程,因為當主程序中的代碼執行完后,主線程就可以結束了,這時候被設定為守護線程的兩個子線程會被殺死,然后主線程結束。x3w28資訊網——每日最新資訊28at.com

注意,當前臺線程死亡后,Python 解釋器會通知后臺線程死亡,但是從它接收指令到做出響應需要一定的時間。如果要將某個線程設置為后臺線程,則必須在該線程啟動之前進行設置。也就是說,將 daemon 屬性設為 True,必須在 start() 方法調用之前進行,否則會引發 RuntimeError 異常。x3w28資訊網——每日最新資訊28at.com

x3w28資訊網——每日最新資訊28at.com

若將兩個子線程的其中一個設置為守護線程,另一個設置為非守護線程:x3w28資訊網——每日最新資訊28at.com

# -*- coding: utf-8 -*-import datetimeimport timeimport threadingclass MyThread(threading.Thread):    def __init__(self, n):        self.n = n        # 注意:一定要調用父類的初始化函數,否則無法創建線程        super().__init__()    def run(self) -> None:        while True:            _count = threading.active_count()            threading_name = threading.current_thread().getName()            times = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')            print(f'{times}-{self.n}-"當前活躍的線程個數:{_count}"-"當前線程的名稱是":{threading_name}')            time.sleep(self.n)for i in range(1, 3):    t = MyThread(i)    if i == 1:        t.setDaemon(True)    t.start()    print(threading.current_thread().getName()) # 輸出2022-12-16 13:30:17-1-"當前活躍的線程個數:2"-"當前線程的名稱是":Thread-1MainThread2022-12-16 13:30:17-2-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-2MainThread2022-12-16 13:30:18-1-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-12022-12-16 13:30:19-1-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-12022-12-16 13:30:19-2-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-22022-12-16 13:30:20-1-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-1...

x3w28資訊網——每日最新資訊28at.com

此時非守護線程作為前臺程序還在繼續執行,守護線程就還有“守護”的意義,就會繼續執行。x3w28資訊網——每日最新資訊28at.com

x3w28資訊網——每日最新資訊28at.com

四、join()方法

不使用join方法

當設置多個線程時,在一般情況下(無守護線程,setDeamon=False),多個線程同時啟動,主線程執行完,會等待其他子線程執行完,程序才會退出。x3w28資訊網——每日最新資訊28at.com

# -*- coding: utf-8 -*-import datetimeimport timeimport threadingclass MyThread(threading.Thread):    def __init__(self, n):        self.n = n        # 注意:一定要調用父類的初始化函數,否則無法創建線程        super().__init__()    def run(self) -> None:        _count = threading.active_count()        threading_name = threading.current_thread().getName()        times = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')        time.sleep(1)        print(f'{times}-{self.n}-"當前活躍的線程個數:{_count}"-"當前線程的名稱是":{threading_name}')start_time = time.time()print(f'{start_time},這是主線程:', threading.current_thread().name)for i in range(5):    t = MyThread(i)    # t.setDaemon(True)    t.start()    # t.join()end_time = time.time()print(f'{end_time},主線程結束了!', threading.current_thread().name)print('一共用時:', end_time - start_time)# 輸出1671174404.6552384,這是主線程:MainThread1671174404.656239,主線程結束了!MainThread一共用時:0.00100064277648925782022-12-16 15:06:44-0-"當前活躍的線程個數:2"-"當前線程的名稱是":Thread-12022-12-16 15:06:44-1-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-22022-12-16 15:06:44-2-"當前活躍的線程個數:4"-"當前線程的名稱是":Thread-32022-12-16 15:06:44-3-"當前活躍的線程個數:5"-"當前線程的名稱是":Thread-42022-12-16 15:06:44-4-"當前活躍的線程個數:6"-"當前線程的名稱是":Thread-5

x3w28資訊網——每日最新資訊28at.com

我們的計時是對主線程計時,主線程結束,計時隨之結束,打印出主線程的用時。主線程的任務完成之后,主線程隨之結束,子線程繼續執行自己的任務,直到全部的子線程的任務全部結束,程序結束。x3w28資訊網——每日最新資訊28at.com

使用join()方法

主線程任務結束之后,進入阻塞狀態,一直等待調用join方法的子線程執行結束之后,主線程才會終止。下面的例子是讓t調用join()方法。x3w28資訊網——每日最新資訊28at.com

# -*- coding: utf-8 -*-import datetimeimport timeimport threadingclass MyThread(threading.Thread):    def __init__(self, n):        self.n = n        # 注意:一定要調用父類的初始化函數,否則無法創建線程        super().__init__()    def run(self) -> None:        _count = threading.active_count()        threading_name = threading.current_thread().getName()        times = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')        time.sleep(1)        print(f'{times}-{self.n}-"當前活躍的線程個數:{_count}"-"當前線程的名稱是":{threading_name}')start_time = time.time()print(f'{start_time},這是主線程:', threading.current_thread().name)for i in range(5):    t = MyThread(i)    # t.setDaemon(True)    t.start()    t.join()end_time = time.time()print(f'{end_time},主線程結束了!', threading.current_thread().name)print('一共用時:', end_time - start_time)# 輸出1671174502.0245655,這是主線程:MainThread2022-12-16 15:08:22-0-"當前活躍的線程個數:2"-"當前線程的名稱是":Thread-12022-12-16 15:08:23-1-"當前活躍的線程個數:2"-"當前線程的名稱是":Thread-22022-12-16 15:08:24-2-"當前活躍的線程個數:2"-"當前線程的名稱是":Thread-32022-12-16 15:08:25-3-"當前活躍的線程個數:2"-"當前線程的名稱是":Thread-42022-12-16 15:08:26-4-"當前活躍的線程個數:2"-"當前線程的名稱是":Thread-51671174507.0313594,主線程結束了!MainThread一共用時:5.006793975830078Process finished with exit code 0

x3w28資訊網——每日最新資訊28at.com

join()方法的timeout參數

join的語法結構為join(timeout=None),可以看到join()方法有一個timeout參數,其默認值為None,而參數timeout可以進行賦值,其含義是指定等待被join的線程的時間最長為timeout秒,也就是說當在timeout秒內被join的線程還沒有執行結束的話,就不再進行等待了。x3w28資訊網——每日最新資訊28at.com

# -*- coding: utf-8 -*-import datetimeimport timeimport threadingclass MyThread(threading.Thread):    def __init__(self, n):        self.n = n        # 注意:一定要調用父類的初始化函數,否則無法創建線程        super().__init__()    def run(self) -> None:        _count = threading.active_count()        threading_name = threading.current_thread().getName()        times = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')        time.sleep(5)        print(f'{times}-{self.n}-"當前活躍的線程個數:{_count}"-"當前線程的名稱是":{threading_name}')start_time = time.time()print(f'{start_time},這是主線程:', threading.current_thread().name)for i in range(5):    t = MyThread(i)    # t.setDaemon(True)    t.start()    t.join(2)end_time = time.time()print(f'{end_time},主線程結束了!', threading.current_thread().name)print('一共用時:', end_time - start_time)# 輸出1671175114.663927,這是主線程:MainThread2022-12-16 15:18:34-0-"當前活躍的線程個數:2"-"當前線程的名稱是":Thread-12022-12-16 15:18:36-1-"當前活躍的線程個數:3"-"當前線程的名稱是":Thread-22022-12-16 15:18:38-2-"當前活躍的線程個數:4"-"當前線程的名稱是":Thread-31671175124.6681008,主線程結束了!MainThread一共用時:10.0041737556457522022-12-16 15:18:40-3-"當前活躍的線程個數:4"-"當前線程的名稱是":Thread-42022-12-16 15:18:42-4-"當前活躍的線程個數:4"-"當前線程的名稱是":Thread-5Process finished with exit code 0

本文鏈接:http://www.tebozhan.com/showinfo-26-12384-0.htmlPython多線程詳細體驗

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Go 并發可視化解釋 - Semaphore

下一篇: Python在工業自動化領域的應用詳解

標簽:
  • 熱門焦點
Top