示例
返回活躍線程的數量
In [1]: import threading
In [2]: threading.active_count()
Out[2]: 22
In [3]: len(threading.enumerate())
Out[3]: 22
返回活躍線程列表
In [1]: import threading
In [2]: threading.enumerate()
Out[2:
[<_MainThread(MainThread, started 3744)>,
<HistorySavingThread(IPythonHistorySavingThread, started 9356)>,
<Thread(ThreadPoolExecutor-0_0, started daemon 6552)>,
<Thread(ThreadPoolExecutor-0_1, started daemon 9492)>,
<Thread(ThreadPoolExecutor-0_2, started daemon 8740)>,
<Thread(ThreadPoolExecutor-0_3, started daemon 4128)>,
<Thread(ThreadPoolExecutor-0_4, started daemon 288)>,
<Thread(ThreadPoolExecutor-0_5, started daemon 2804)>,
<Thread(ThreadPoolExecutor-0_6, started daemon 5848)>,
<Thread(ThreadPoolExecutor-0_7, started daemon 9608)>,
<Thread(ThreadPoolExecutor-0_8, started daemon 6348)>,
<Thread(ThreadPoolExecutor-0_9, started daemon 7156)>,
<Thread(ThreadPoolExecutor-0_10, started daemon 4268)>,
<Thread(ThreadPoolExecutor-0_11, started daemon 7364)>,
<Thread(ThreadPoolExecutor-0_12, started daemon 7532)>,
<Thread(ThreadPoolExecutor-0_13, started daemon 5888)>,
<Thread(ThreadPoolExecutor-0_14, started daemon 364)>,
<Thread(ThreadPoolExecutor-0_15, started daemon 5816)>,
<Thread(ThreadPoolExecutor-0_16, started daemon 9636)>,
<Thread(ThreadPoolExecutor-0_17, started daemon 6756)>,
<Thread(ThreadPoolExecutor-0_18, started daemon 10080)>,
<Thread(ThreadPoolExecutor-0_19, started daemon 7264)>]
創建一個線程
In [1]: import threading
In [2]: thread = threading.Thread()
In [3]: thread
Out[3]: <Thread(Thread-1, initial)>
爲線程綁定任務
In [1]: import threading
In [2]: thread = threading.Thread()
In [3]: def f1():
...: print("Her")
...:
In [4]: thread.target = f1
In [5]: thread.target
Out[5]: <function __main__.f1()>
或
In [1]: import threading
In [2]: def f1():
...: print("Her")
...:
In [2]: thread = threading.Thread(target=f1)
爲線程任務傳遞參數
In [1]: import threading
In [2]: def f1(i):
...: print("Her"+str(i))
...:
In [2]: thread = threading.Thread(target=f1, args=(666,))
運行線程
In [1]: import threading
In [2]: def f1(i):
...: print("Her"+str(i))
...:
In [2]: thread = threading.Thread(target=f1, args=(666,))
In [3]: thread.start()
Her666
注意:
In [1]: thread.run() Her666
- start() 方法是啓動一個子線程
- run() 方法並不啓動一個新線程,而是在主線程中調用了任務函數。
- start() 它在一個線程裏最多隻能被調用一次。
阻塞調用的線程 (守護線程)
不使用 join()
:
import threading
import time
def f1():
for i in range(2):
print("thread1", time.ctime())
time.sleep(1)
thread1 = threading.Thread(target=f1)
thread1.start()
print("done")
輸出:
thread1 Wed Mar 18 18:52:23 2020
done
thread1 Wed Mar 18 18:52:24 2020
使用 join()
:
import threading
import time
def f1():
for i in range(2):
print("thread1", time.ctime())
time.sleep(1)
thread1 = threading.Thread(target=f1)
thread1.start()
thread1.join()
print("done")
輸出:
thread1Wed Mar 18 18:55:55 2020
thread1Wed Mar 18 18:55:56 2020
done
使用 join()
會將調用這個線程的主線程阻塞,等待當前線程終止後纔將控制權交還給主線程。
多線程訪問臨界值
import threading
import time
a = 0
def f1():
global a
t = a + 1
print(t)
time.sleep(1) # 模擬修改變量值的時間過程
a = t
threads = [threading.Thread(target=f1) for _ in range(5)]
for _ in threads:
_.start()
輸出:
1
1
1
1
1
CPU 太快了,導致 time.sleep(1)
休眠沒有結束就跑完所有線程,此時線程獲取到 a
的值都是 0
線程鎖
# 創建線程鎖
lock = threading.Lock()
# 獲得鎖
lock.acquire()
# 釋放鎖
lock.release()
爲臨界資源加鎖:
import threading
import time
lock = threading.Lock()
a = 0
def f1():
global a
lock.acquire()
t = a + 1
print(t)
time.sleep(1) # 模擬修改變量值的時間過程
a = t
lock.release()
threads = [threading.Thread(target=f1) for _ in range(5)]
for _ in threads:
_.start()
輸出:
1
2
3
4
5
參考
threading.active_count()
: 返回當前活躍的線程對象的數量
threading.current_thread()
: 返回當前線程對象
threading.excepthook(args, /)
: 處理 Thread.run()
未捕獲的異常
threading.get_ident()
: 返回當前線程的索
threading.get_native_id()
: 返回內核分配給當前線程的原生集成線程 ID
threading.enumerate()
: 以列表形式返回當前所有存活的 Thread 對象
threading.main_thread()
: 返回主 Thread 對象
threading.settrace(func)
: 爲所有 threading 模塊開始的線程設置追蹤函數
threading.setprofile(func)
: 爲所有 threading 模塊開始的線程設置性能測試函數
threading.stack_size([size])
: 返回創建線程時用的堆棧大小
threading.TIMEOUT_MAX
: 阻塞函數( Lock.acquire(), RLock.acquire(), Condition.wait(), …)中形參 timeout 允許的最大值
threading.local()
:創建本地線程數據
線程對象
threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
: 創建線程對象
參數 | 說明 |
---|---|
group | group 應該爲 None ;爲了日後擴展 ThreadGroup 類實現而保留 |
target | 用於 run() 方法調用的可調用對象 |
name | 線程名稱 |
args | 調用目標函數的參數元組 |
kwargs | 用目標函數的關鍵字參數字典 |
daemon | 是否爲守護模式,默認值 None 爲線程將繼承當前線程的守護模式屬性 |
start()
:開始線程活動。
run()
:代表線程活動的方法。 標準的 run()
方法會對作爲 target
參數傳遞給該對象構造器的可調用對象(如果存在)發起調用,並附帶從 args
和 kwargs
參數分別獲取的位置和關鍵字參數
join(timeout=None)
: 等待,直到線程終結。
name
:只用於識別的字符串。
getName()
,setName()
:獲取/設置 name
的值。
ident
:這個線程的 ‘線程標識符’
native_id
:該線程的當前線程ID。
is_alive()
:返回線程是否存活。
daemon
:一個表示這個線程是(True)否(False)守護線程的布爾值。
isDaemon()
,setDaemon()
:獲取/設置 name
的值。
鎖對象
threading.Lock()
:創建所。
acquire(blocking=True, timeout=-1)
:可以阻塞或非阻塞地獲得鎖。
release()
:釋放一個鎖。
locked()
:如果獲得了鎖則返回真值。