您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關python實現多線程的方法,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
python實現多線程的方法:
1、Thread直接創建子線程
首先可以使用 Thread 類來創建一個線程,創建時需要指定 target 參數為運行的方法名稱,如果被調用的方法需要傳入額外的參數,則可以通過 Thread 的 args 參數來指定。
import threading import time def target(second): print(f'Threading {threading.current_thread().name} is running') print(f'Threading {threading.current_thread().name} sleep {second}s') time.sleep(second) print(f'Threading {threading.current_thread().name} is ended') print(f'Threading {threading.current_thread().name} is running') for i in [1, 5]: thread = threading.Thread(target=target, args=[i]) thread.start() print(f'Threading {threading.current_thread().name} is ended')
運行結果:
Threading MainThread is running Threading Thread-1 is running Threading Thread-1 sleep 1s Threading Thread-2 is running Threading Thread-2 sleep 5s Threading MainThread is ended Threading Thread-1 is ended Threading Thread-2 is ended
如果想要主線程等待子線程運行完畢之后才退出,可以讓每個子線程對象都調用下 join 方法:
threads = [] for i in [1, 5]: thread = threading.Thread(target=target, args=[i]) threads.append(thread) thread.start() for thread in threads: thread.join()
運行結果:
Threading MainThread is running Threading Thread-1 is running Threading Thread-1 sleep 1s Threading Thread-2 is running Threading Thread-2 sleep 5s Threading Thread-1 is ended Threading Thread-2 is ended Threading MainThread is ended
2、繼承Thread類創建子線程
另外也可以通過繼承 Thread 類的方式創建一個線程,該線程需要執行的方法寫在類的 run 方法里面即可。上面的例子的等價改寫為:
import threading import time class MyThread(threading.Thread): def __init__(self, second): threading.Thread.__init__(self) self.second = second def run(self): print(f'Threading {threading.current_thread().name} is running') print(f'Threading {threading.current_thread().name} sleep {self.second}s') time.sleep(self.second) print(f'Threading {threading.current_thread().name} is ended') print(f'Threading {threading.current_thread().name} is running') threads = [] for i in [1, 5]: thread = MyThread(i) threads.append(thread) thread.start() for thread in threads: thread.join() print(f'Threading {threading.current_thread().name} is ended')
運行結果:
Threading MainThread is running Threading Thread-1 is running Threading Thread-1 sleep 1s Threading Thread-2 is running Threading Thread-2 sleep 5s Threading Thread-1 is ended Threading Thread-2 is ended Threading MainThread is ended
守護線程
在線程中有一個叫作守護線程的概念,如果一個線程被設置為守護線程,那么意味著這個線程是“不重要”的,這意味著,如果主線程結束了而該守護線程還沒有運行完,那么它將會被強制結束。
在 Python 中我們可以通過 setDaemon 方法來將某個線程設置為守護線程:
import threading import time def target(second): print(f'Threading {threading.current_thread().name} is running') print(f'Threading {threading.current_thread().name} sleep {second}s') time.sleep(second) print(f'Threading {threading.current_thread().name} is ended') print(f'Threading {threading.current_thread().name} is running') t1 = threading.Thread(target=target, args=[2]) t1.start() t2 = threading.Thread(target=target, args=[5]) t2.setDaemon(True) t2.start() print(f'Threading {threading.current_thread().name} is ended')
運行結果:
Threading MainThread is running Threading Thread-1 is running Threading Thread-1 sleep 2s Threading Thread-2 is running Threading Thread-2 sleep 5s Threading MainThread is ended Threading Thread-1 is ended
互斥鎖
在一個進程中的多個線程是共享資源的,比如在一個進程中,有一個全局變量 count 用來計數,現在聲明多個線程,每個線程運行時都給 count 加 1,代碼實現如下:
import threading import time count = 0 class MyThread(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): global count temp = count + 1 time.sleep(0.001) count = temp threads = [] for _ in range(1000): thread = MyThread() thread.start() threads.append(thread) for thread in threads: thread.join() print(f'Final count: {count}')
運行結果:
Final count: 69
由于 count 這個值是共享的,每個線程都可以在執行 temp = count 這行代碼時拿到當前 count 的值,但是這些線程中的一些線程可能是并發或者并行執行的,這就導致不同的線程拿到的可能是同一個 count 值,最后導致有些線程的 count 的加 1 操作并沒有生效,導致最后的結果偏小。
所以,如果多個線程同時對某個數據進行讀取或修改,就會出現不可預料的結果。為了避免這種情況,我們需要對多個線程進行同步,要實現同步,我們可以對需要操作的數據進行加鎖保護,這里就需要用到 threading.Lock 了。
加鎖保護
某個線程在對數據進行操作前,需要先加鎖,這樣其他的線程發現被加鎖了之后,就無法繼續向下執行,會一直等待鎖被釋放,只有加鎖的線程把鎖釋放了,其他的線程才能繼續加鎖并對數據做修改,修改完了再釋放鎖。
這樣可以確保同一時間只有一個線程操作數據,多個線程不會再同時讀取和修改同一個數據。
關于python實現多線程的方法就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。