什么是線程?
線程是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以並發多個線程,每條線程並行執行不同的任務
Python3中實現多線程有兩種方式
1.直接實例化threading.Thread線程對象,實現多線程

import threading import time def print_age(who, age): """ 需要用多線程調用的函數 :param who: :param age: :return: """ print("Hello,every one!") time.sleep(1) print("%s is %s years old !" % (who, age)) if __name__ == "__main__": t1 = threading.Thread(target=print_age, args=("jet", 18, )) # 創建線程1 t2 = threading.Thread(target=print_age, args=("jack", 25, )) # 創建線程2 t3 = threading.Thread(target=print_age, args=("jack", 25,)) # 創建線程3 t1.start() # 運行線程1 t2.start() # 運行線程2 t3.start() # 運行線程3 print("over...")
2.通過繼承threading.Thread,並重寫run()方法,來實現多線程

import threading import time class MyThread(threading.Thread): """ 使用繼承的方式實現多線程 """ def __init__(self, who): super().__init__() # 必須調用父類的構造方法 self.name = who def run(self): print("%s is run..." % self.name) time.sleep(3) if __name__ == "__main__": t1 = MyThread("Jet") # 創建線程1 t2 = MyThread("Jack") # 創建線程2 t1.start() # 運行線程1 t2.start() # 運行線程2 print("over...")
守護線程
可以通過setDaemon()方法將線程設置為守護線程,當守護線程退出時,由它啟動的其它子線程將同時退出,不管是否執行完成

import threading import time def print_age(who, age): print("Hello,every one!") time.sleep(1) print("%s is %s years old !" % (who, age)) def daemon_func(): for i in range(18, 25): t = threading.Thread(target=print_age, args=("Jet", i,)) # 創建線程 t.start() if __name__ == "__main__": dt = threading.Thread(target=daemon_func) # 創建線程 dt.setDaemon(True) # 設置為守護線程 dt.start() dt.join(timeout=2) print("over...")
線程鎖
因為多線程是共享父進程里面的數據的,所以當多個線程同時修改一份數據的時候,就容易出錯,因此就有了鎖,鎖能確保在同一時間只有一個線程修改這份數據
CPython的GIL(Global Interpreter Lock)是全局線程鎖,是確保只有一個線程運行的,與這個鎖沒有關系,鎖的層級不一樣,GIL更為底層

# -*- coding: utf-8 -*- import threading import time def add_one(): global num print("Value: %s" % num) time.sleep(1) lock.acquire() # 加鎖 num += 1 # 修改數據 lock.release() # 釋放鎖 if __name__ == "__main__": num = 0 lock = threading.RLock() # 一般都用RLock遞歸鎖 thread_list = [] for i in range(100): t = threading.Thread(target=add_one) t.start() thread_list.append(t) for i in thread_list: i.join() print("Num = %s" % num)
信號量
信號量semaphore,是一個變量,控制着對公共資源或者臨界區的訪問。信號量維護着一個計數器,指定可同時訪問資源或者進入臨界區的線程數。用來控制最大線程數的

# -*- coding: utf-8 -*- import threading import time def add_one(): global num semaphore.acquire() # 加鎖,最多有五個線程做以下操作 time.sleep(1) num -= 1 print("Value: %s" % num) semaphore.release() # 釋放鎖 if __name__ == "__main__": num = 100 thread_list = [] semaphore = threading.BoundedSemaphore(5) for i in range(100): t = threading.Thread(target=add_one) t.start() thread_list.append(t) for i in thread_list: i.join() # 等待線程結束 print("Num = %s" % num)
參考資料
http://python.usyiyi.cn/translate/python_352/library/threading.html