python多線程——獲取子線程中的值

python多線程——獲取子線程中的值

點擊上方“python學習專欄”,選擇“置頂公眾號”

​乾貨、福利第一時間送達!


如何開啟多線程?


1、定義自己的函數

2、加入線程

3、啟動線程

4、等待線程結束


看下面的代碼

<code>from threading import Thread
import time
# 定義一個函數,等待5秒後輸出data
def fun():
    data = "123"
    time.sleep(5)
    print(data)
    return data
​
if __name__ == "__main__":
    #定義一個線程,target為需要執行的目標函數
    T = Thread(target=fun)
    # 啟動子線程
    T.start()
    print("結束")
​
​
# 輸出結果為
# 結束
# 123/<code>


假設這裡不加入多線程,而是直接調用,那麼輸出應該是

123

結束


分析一下過程,if _name__ == "__main__" 相當於一個主線程,而 T 是我們定義的一個子線程,T.start(),開啟子線程。

由於這裡沒有規定,讓主線程等待子線程結束,因此會提前輸出 結束


開啟主線程等待

<code>from threading import Thread
import time
# 定義一個函數,等待5秒後輸出data
def fun():
    data = "123"
    time.sleep(5)
    print(data)
    return data
if __name__ == "__main__":
    #定義一個線程,target為需要執行的目標函數
    T = Thread(target=fun)
    # 啟動子線程
    T.start()
    # 主線程需要等待子線程結束
    T.join()
    print("結束")
​
# 輸出結果為
# 123
# 結束/<code>


這裡只是簡單的講一下線程的操作


如何獲取線程中產生的值


首先需要說一下,在線程中,使用return 返回值是不能實現的,你不能拿到這個值,無論你是否開啟線程等待。可以自行嘗試一下


想要實現這個功能,有兩個方法,


1、重寫 Thread

重寫 Thread,在內部定義一個獲取值的函數

<code>import threading
class MyThread(threading.Thread):
    """重寫多線程,使其能夠返回值"""
    def __init__(self, target=None, args=()):
        super(MyThread, self).__init__()
        self.func = target
        self.args = args
​
    def run(self):
        self.result = self.func(*self.args)
    #該函數用於獲取返回值,需要開啟join
    def get_result(self):
        try:
            return self.result  
        except Exception:
            return None/<code>


使用自定義的類來實現

<code>from threading import Thread
import time
# 定義一個函數,等待5秒後返回data
def fun():
    data = "123"
    time.sleep(5)
    return data
if __name__ == "__main__":
    #定義一個線程,target為需要執行的目標函數
    T = MyThread(target=fun)
    # 啟動子線程
    T.start()
    # 主線程需要等待子線程結束
​
    T.join()
    # 獲取值必須放在 join後面,
    print(T.get_result())
    print("結束")
​
# 輸出結果為
# 123
# 結束/<code>


join是讓主線程等待子線程結束,如果將獲取結果放到了主線程join前,此時程序為運行結束,返回值為空


2、使用隊列實現


首先定義一個全局隊列,將多線程產生的值放到隊列中,然後在主線程中獲取。

<code>from threading import Thread
from queue import Queue
import time
​
# 定義一個全局隊列,先進先出隊列
queue_data = Queue()
​
# 定義一個函數,等待5秒後輸出data
def fun():
    data = "123"
    time.sleep(5)
    # 將數據壓入隊列
    queue_data.put(data)
​
if __name__ == "__main__":
    #定義一個線程,target為需要執行的目標函數
    T = Thread(target=fun)
    # 啟動子線程
    T.start()
    w = T.join()
    print(queue_data.get())
    print("結束")
# 輸出結果為
​
# 123
# 結束/<code>


藉助concurrent模塊,加入線程池中來實現


通過線程池的自帶函數獲取結果

<code>from threading import Thread
from queue import Queue
from concurrent.futures import ThreadPoolExecutor
import time
​
# 定義一個全局隊列,先進先出隊列
queue_data = Queue()
pool = ThreadPoolExecutor()
​
# 定義一個函數,等待5秒後輸出data
def fun():
    data = "123"
    time.sleep(5)
    # 將數據壓入隊列
    queue_data.put(data)
    return data
    
if __name__ == "__main__":
    #定義一個線程,target為需要執行的目標函數
    t = pool.submit(fun)
    print(t.result())
    print("結束")
# 輸出結果為
​
# 123
# 結束/<code>


判斷線程是否結束

<code>from threading import Thread
from queue import Queue
from concurrent.futures import ThreadPoolExecutor
import time
​
# 定義一個全局隊列,先進先出隊列
queue_data = Queue()
pool = ThreadPoolExecutor()
​
# 定義一個函數,等待5秒後輸出data
def fun():
    data = "123"
    time.sleep(5)
    # 將數據壓入隊列
    queue_data.put(data)
    return data
    
if __name__ == "__main__":
    #定義一個線程,target為需要執行的目標函數
    t = pool.submit(fun)
    # 判斷線程是否結束
    print(t.done())
    print("結束")
# 輸出結果為
​
# False
# 結束/<code> 

通過判斷線程是否結束,採用while循環最終獲取結果


如覺得文章排版不適應,可以到我的同名公眾號閱讀


點贊+關注

END


python多線程——獲取子線程中的值


分享到:


相關文章: