Python是一種非常流行的編程語言,因為它具有易讀易學及允許以高效率完成大量任務的特點。但是,Python 解釋器設計的實現方式意味著它在大量多線程的執行上可能會遇到一些問題。具體來說,Python 解釋器通過需要全局變量鎖來進行管理,這就意味著在實際的實現過程中,只能允許一個線程集中執行代碼。
import threading a = 0 def add_a(): global a for i in range(1000000): a += 1 def sub_a(): global a for i in range(1000000): a -= 1 t1 = threading.Thread(target=add_a) t2 = threading.Thread(target=sub_a) t1.start() t2.start() t1.join() t2.join() print(a)
在上述代碼中,通過多個線程分別增加和減少變量a的值。預期結果應該在兩個線程同時運行之后,變量a的值不變。但是,實際我們可能會得到一些不同的結果。 比如我們可以得到- vi1的結果或者 12705的結果。在這個具體的例子中,這是因為不同進程搶奪全局鎖導致的。
因為這種全局鎖的存在,當一個線程在運行時,其他線程必須等待鎖釋放才能運行。這也就意味著,如果一個線程占用著GIL,那么它等待期間阻止了其他一切線程的運行。因此,Python 解釋器實現上的 GIL 瓶頸會使得 Python 的多線程實現效果受到嚴重限制。
當然,對于并行執行IO密集型操作的情況,Python的多線程實現是很適合的。但是,在必須要進行CPU密集型操作時,最好的選擇往往是使用多進程實現并行運算。