激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - python 深入了解GIL鎖詳細

python 深入了解GIL鎖詳細

2022-02-18 00:29Silent丿丶黑羽 Python

這篇文章主要介紹了python 深入了解GIL鎖,python的使用者都知道Cpython解釋器有一個弊端,真正執行時同一時間只會有一個線程執行,這是由于設計者當初設計的一個缺陷,里面有個叫GIL鎖的,但他到底是什么,接下來和小編一起進入

前言:

python的使用者都知道Cpython解釋器有一個弊端,真正執行時同一時間只會有一個線程執行,這是由于設計者當初設計的一個缺陷,里面有個叫GIL鎖的,但他到底是什么?我們只知道因為他導致python使用多線程執行時,其實一直是單線程,但是原理卻不知道,那么接下來我們就認識一下GIL鎖

1、什么是GIL鎖

GIL(Global Interpreter Lock)不是Python獨有的特性,它只是在實現CPython(Python解釋器)時,引入的一個概念。

在官方網站中定義如下:

In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython's memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)

由定義可知,GIL是一個互斥鎖(mutex)。它阻止了多個線程同時執行Python字節碼,毫無疑問,這降低了執行效率。理解GIL的必要性,需要了解CPython對于線程安全的內存管理機制。

2、CPython對線程安全的內存管理機制

Python使用引用計數來進行內存管理,在Python中創建的對象都會有引用計數,來記錄有多少個指針指向它。當引用計數的值為0時,就會自動釋放內存

我們來看一個小例子,來解釋引用計數的原理:

?
1
2
3
4
5
>>> import sys
>>> a = []
>>> b = a
>>> sys.getrefcount(a)
3

可以看到,a 的引用計數值為 3,因為有 ab 和作為參數傳遞的 getrefcount 都引用了一個空列表。
如果有2個python線程同時引用a,那么2個線程都會嘗試對其進行數據操作,多個線程同時對一個數據進行增加或減少的操作,如果發生這種情況,則可能導致內存泄漏

3、GIL鎖的產生

由于多個線程同時對數據進行操作,會引發數據不一致,導致內存泄漏,我們可以對其進行加鎖,所以Cpython就創建了GIL

但是既然有了鎖,一個對象就需要一把鎖,那么多個對象就會有多把鎖,可能會給我們帶來2個問題

  • 1.死鎖(線程之間互相爭搶鎖的資源)
  • 2.反復獲取和釋放鎖而導致性能降低。

為了保證單線程情況下python的正常執行和效率,GIL鎖(單一鎖)由此產生了,它添加了一個規則,即任何Python字節碼的執行都需要獲取解釋器鎖。這樣可以防止死鎖(因為只有一個鎖),并且不會帶來太多的性能開銷。但這實際上使所有受CPU約束的Python程序(指的是CPU密集型程序)都是單線程的。

4、GIL鎖的底層原理

python 深入了解GIL鎖詳細

上面這張圖,就是 GIL Python 程序的工作示例。其中,Thread 123 輪流執行,每一個線程在開始執行時,都會鎖住 GIL,以阻止別的線程執行;同樣的,每一個線程執行完一段后,會釋放 GIL,以允許別的線程開始利用資源。

線程釋放GIL鎖有兩種情況:

  • 一是遇到IO操作
  • 二是Time Tick到期。IO操作很好理解

比如發出一個http請求,等待響應。那么Time Tick到期是什么呢?Time Tick規定了線程的最長執行時間,超過時間后自動釋放GIL鎖。Python 3 以后,間隔時間大致為15毫秒
 

雖然都是釋放GIL鎖,但這兩種情況是不一樣的。比如,Thread1遇到IO操作釋放GIL,由Thread2和Thread3來競爭這個GIL鎖,Thread1不再參與這次競爭。如果是Thread1因為Time Tick到期釋放GIL(多數是CPU密集型任務),那么三個線程可以同時競爭這把GIL鎖,可能出現Thread1在競爭中勝出,再次執行的情況。單核CPU下,這種情況不算特別糟糕。因為只有1個CPU,所以CPU的利用率是很高的。

在多核CPU下,由于GIL鎖的全局特性,無法發揮多核的特性,GIL鎖會使得多線程任務的效率大大降低。

python 深入了解GIL鎖詳細

Thread1在CPU1上運行,Thread2在CPU2上運行。GIL是全局的,CPU2上的Thread2需要等待CPU1上的Thread1讓出GIL鎖,才有可能執行。如果在多次競爭中,Thread1都勝出,Thread2沒有得到GIL鎖,意味著CPU2一直是閑置的,無法發揮多核的優勢。

為了避免同一線程霸占CPU,在python3.2版本之后,線程會自動的調整自己的優先級,使得多線程任務執行效率更高。
既然GIL降低了多核的效率,那保留它的目的是什么呢?這就和線程執行的安全有關。

5、Python GIL不能絕對保證線程安全

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def add():
    global n
    for i in range(10**1000):
        n = n +1
def sub():
    global n
    for i in range(10**1000):
        n = n - 1
n = 0
import threading
a = threading.Thread(target=add,)
b = threading.Thread(target=sub,)
a.start()
b.start()
a.join()
b.join()
print n

上面的程序對n做了同樣數量的加法和減法,那么n理論上是0。但運行程序,打印n,發現它不是0。問題出在哪里呢,問題在于python的每行代碼不是原子化的操作。比如n = n+1這步,不是一次性執行的。如果去查看python編譯后的字節碼執行過程,可以看到如下結果。

?
1
2
3
4
19 LOAD_GLOBAL              1 (n)
22 LOAD_CONST               3 (1)
25 BINARY_ADD         
26 STORE_GLOBAL             1 (n)

從過程可以看出,n = n +1操作分成了四步完成。因此,n = n+1不是一個原子化操作。

  • 1.加載全局變量n
  • 2.加載常數1
  • 3.進行二進制加法運算
  • 4.將運算結果存入變量n。

根據前面的線程釋放GIL鎖原則,線程a執行這四步的過程中,有可能會讓出GIL。如果這樣,n=n+1的運算過程就被打亂了。最后的結果中,得到一個非零的n也就不足為奇。

6、總結

對于IO密集型應用,多線程的應用和多進程應用區別不大。即便有GIL存在,由于IO操作會導致GIL釋放,其他線程能夠獲得執行權限。由于多線程的通訊成本低于多進程,因此偏向使用多線程。

對于計算密集型應用,由于CPU一直處于被占用狀態,GIL鎖直到規定時間才會釋放,然后才會切換狀態,導致多線程處于絕對的劣勢,此時可以采用多進程+協程。

到此這篇關于python 深入了解GIL鎖詳細的文章就介紹到這了,更多相關python 深入了解GIL鎖內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

參考資料:

https://realpython.com/python-gil/
https://zhuanlan.zhihu.com/p/97218985

原文鏈接:https://www.cnblogs.com/jiakecong/p/14693491.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: av电影在线免费 | a视频网站 | 一级电影在线观看 | 91久久国产露脸精品免费 | 91久久久久久久久久久久久 | 精品一区二区三区在线观看视频 | 成人在线免费视频观看 | 91av资源在线 | 中文字幕在线观看1 | av成人在线电影 | 黄在线 | 高清av免费 | 国产精品国产三级国产aⅴ无密码 | 欧美精品免费一区二区三区 | 在线成人一区二区 | 精品国产呦系列在线看 | 人人玩人人爽 | 欧美中文字幕一区二区 | 国产理论视频在线观看 | 国产做爰| 黄色欧美精品 | lutube成人福利在线观看 | 特片网久久 | 情侣啪啪网站 | 一级做a爱片久久毛片a高清 | 操碰| 成人毛片一区二区三区 | av成人在线电影 | 免费在线观看中文字幕 | 久久精品4 | 毛片免费在线观看视频 | 麻豆视频在线免费观看 | 在线亚洲欧美日韩 | 久久精品成人影院 | 亚洲欧美在线视频免费 | 成人 精品 | 中文字幕观看 | 中文字幕免费播放 | 美女黄污视频 | 香蕉久久久精品 | 91精品动漫在线观看 |