list
是python
常用的幾個基本資料型別之一.正常情況下我們會對list
有增刪改查的操作,顯然易見不會有任何問題.那麼如果我們試著在多執行緒下操作list
會有問題嗎?
通常我們說的執行緒安全是指針對某個資料結構的所有操作都是執行緒安全,在這種定義下,python 常用的資料結構list,dict,str
等都是執行緒不安全的
對於執行緒安全不安全,我們可以通過極端條件下去復現,從而得出結論。比如說判斷list
是否執行緒安全
import threading
import time
# 隨意設定 count 的值,值越大錯誤丟擲的越快
count =
1000
l =[
]def
add():
for i in
range
(count)
: 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)
有時候一次執行並不一定就會出錯,多次重試之後會出現類似下面的錯誤
很顯然這種操作方式不具有普適性,如果要是歐氣太強,說不定會一直不出現異常。
那麼出了這種方式,有沒有比較簡單有效的方法嗎?答案是有的
dis 庫是 python 自帶的乙個庫,可以用來分析位元組碼。這裡我們需要有這樣的認識,位元組碼的每一行都是乙個原子操作,多執行緒切換就是以原子操作為單位的,如果乙個操作需要兩行位元組碼就說明它是執行緒不安全的
這裡我們先看一下上面list
的remove
操作
>>
>
import dis
>>
>
deftest_remove()
:... a =[1
]... a.remove(0)
...>>
> dis.dis(test_remove)
20 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
操作被分成了好幾條指令,這就意味著在多執行緒情況下會出現錯亂的情況,試想一下,如果多執行緒下都去remove
列表的話,並且不按照順序,很容易出現問題。
8
19 load_global 0
(a)22 load_attr 2
25 load_const 2(1
)28 call_function 1
31 pop_top
python多執行緒 python多執行緒
通常來說,多程序適用於計算密集型任務,多執行緒適用於io密集型任務,如網路爬蟲。關於多執行緒和多程序的區別,請參考這個 下面將使用python標準庫的multiprocessing包來嘗試多執行緒的操作,在python中呼叫多執行緒要使用multiprocessing.dummy,如果是多程序則去掉...
python多執行緒 Python多執行緒的一些知識
了更好地體驗多執行緒爬蟲,本章先介紹下需要了解的知識點,以便後續的多執行緒爬蟲文章有更好的理解與學習。在接下來要講的知識點中,感興趣的讀者們請先弄清楚程序和執行緒兩者是什麼?它們各自有著什麼樣的關係呢?讀下廖雪峰老師簡單介紹的例子,比喻非常生動清晰,故這裡不多做講解。程序和執行緒 www.liaox...
python多執行緒鎖 python的多執行緒程式設計之鎖
1 背景概述 在python中,要保證資料的正確性,並且自己對資料進行控制,對資料進行加鎖並且自己釋放鎖。多執行緒的主要目的為了提高效能與速度,用在無關的方向是最好的,例如在使用爬蟲的時候,可以使用多執行緒來進行爬取資料,因為在這些執行緒之間沒有需要共同操作的資料,從而在這個時候利用是最好的。如果需...