一 背景
在 Cpython中,由于GIL的存在,所以一次同時只能有一個執行緒占用CPU,但是即便如此,python 仍然存在執行緒不安全問題(下文解答), 但是在python中,協程卻是安全的
二 詳情
import eventlet
import threading
count = 0
def count_10000():
global count
for i in range(100000):
count += 1
def count_in_threads():
threads = []
for i in range(5):
t = threading.Thread(target=count_10000)
threads.append(t)
t.start()
for t in threads:
t.join()
def count_in_coroutines():
pool = eventlet.GreenPool()
for i in range(5):
pool.spawn_n(count_10000)
pool.waitall()
count_in_threads()
print(count) # 多執行緒執行,回傳結果會出現隨,并不一定是500000
count = 0
count_in_coroutines() # 多協程執行, 協程安全,一定等于500000
print(count)
首先看下Cpython的中的執行緒切換模式, 不同執行緒輪流占用cpu
但是由于執行緒切換是隨機切換的,不能保證加載資料到執行緒的背景關系的時候(未執行計算前),資料是原子操作的, 所以在多執行緒情況下資料會“不正確”

為什么多協程下資料又是安全的呢?相比多執行緒切換是系統隨機的,協程切換的條件如下:
- sleep:如 eventlet.sleep()
- IO:比如網路 IO,磁盤 IO 等,
所以多協程執行cpu的計算任務 count++ 時候,從讀資料到最后寫資料都是一次完整的操作,并沒有切換協程,也就保證的資料安全
三 總結
python中多協程是安全的,不需要額外的加鎖操作來保證資料一致性,同時隨便提下,golang中協程能夠使用多核CPU,所以使用Chanel(存在互斥鎖)等方式保證了資料一致性
四 參考
感謝作者,學到了
協程安全
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/293100.html
標籤:其他
上一篇:在Kali Linux下使用metasploit 的“永恒之藍“漏洞對 Windows 7 進行攻擊 滲透測驗
下一篇:[MRCTF2020]Ezpop
