list 是 Python 常用的幾個基本數(shù)據(jù)類型之一.正常情況下我們會對 list 有增刪改查的操作,顯然易見不會有任何問題.那么如果我們試著在多線程下操作list 會有問題嗎?
多線程下的 list
安全 or 不安全? 不安全!
通常我們說的線程安全是指針對某個數(shù)據(jù)結(jié)構(gòu)的所有操作都是線程安全,在這種定義下,Python 常用的數(shù)據(jù)結(jié)構(gòu) list,dict,str
等都是線程不安全的
盡管多線程下的 list
是線程不安全的,但是在 append
的操作下是它又是線程安全的.
如何判斷線程安全呢?
對于線程安全不安全,我們可以通過極端條件下去復(fù)現(xiàn),從而得出結(jié)論。比如說判斷 list
是否線程安全
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
import threading import time # 隨意設(shè)置 count 的值,值越大錯誤拋出的越快 count = 1000 l = [] def add(): for i in range (count): l.append(i) time.sleep( 0.0001 ) def remove(): for i in range (count): l.remove(i) time.sleep( 0.0001 ) t1 = threading.Thread(target = add) t2 = threading.Thread(target = remove) t1.start() t2.start() t1.join() t2.join() print (l) |
有時候一次運行并不一定就會出錯,多次重試之后會出現(xiàn)類似下面的錯誤
很顯然這種操作方式不具有普適性,如果要是歐氣太強,說不定會一直不出現(xiàn)異常。
那么出了這種方式,有沒有比較簡單有效的方法嗎?答案是有的
dis
dis 庫是 Python 自帶的一個庫,可以用來分析字節(jié)碼。這里我們需要有這樣的認識,字節(jié)碼的每一行都是一個原子操作,多線程切換就是以原子操作為單位的,如果一個操作需要兩行字節(jié)碼就說明它是線程不安全的
remove
這里我們先看一下上面 list
的 remove
操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
>>> import dis >>> def test_remove(): ... a = [ 1 ] ... a.remove( 0 ) ... >>> dis.dis(test_remove) 2 0 LOAD_CONST 1 ( 1 ) 2 BUILD_LIST 1 4 STORE_FAST 0 (a) 3 6 LOAD_FAST 0 (a) 8 LOAD_ATTR 0 (remove) 10 LOAD_CONST 2 ( 0 ) 12 CALL_FUNCTION 1 14 POP_TOP 16 LOAD_CONST 0 ( None ) 18 RETURN_VALUE |
從上面不難看出,整個 remove
操作被分成了好幾條指令,這就意味著在多線程情況下會出現(xiàn)錯亂的情況,試想一下,如果多線程下都去 remove
列表的話,并且不按照順序,很容易出現(xiàn)問題。
append
在最上面我們說到,list
的 append
操作是線程安全的,那么究竟是為什么呢?我們同樣來用 dis
查看一下
1
2
3
4
5
|
8 19 LOAD_GLOBAL 0 (a) 22 LOAD_ATTR 2 (append) 25 LOAD_CONST 2 ( 1 ) 28 CALL_FUNCTION 1 31 POP_TOP |
這里顯然,append
也是有幾條指令,勢必在多線程執(zhí)行的情況下也會發(fā)生交錯,但是對于多線程下我們操作 append
, 我們肯定也不會在乎這個時候 list
到順序問題了,所以我們說它的 append
是線程安全的
參考
https://stackoverflow.com/questions/6319207/are-lists-thread-safe/19728536#19728536
https://docs.python.org/3/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe
以上就是詳解Python多線程下的list的詳細內(nèi)容,更多關(guān)于Python多線程下的list的資料請關(guān)注服務(wù)器之家其它相關(guān)文章!
原文鏈接:https://www.cnblogs.com/leetao94/p/13228360.html