日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

c语言的锁和Python锁,Python中全局解释器锁、多线程和多进程

發布時間:2023/12/15 python 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言的锁和Python锁,Python中全局解释器锁、多线程和多进程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

全局解釋器鎖(GIL)只允許1個Python線程控制Python解釋器。這也就意味著同一時間點只能有1個Python線程運行。如果你的Python程序只有一個線程,那么全局解釋器鎖可能對你的影響不大,但是如果你的程序是CPU密集型同時使用了多線程,那么程序運行可能會受到很大影響。全局解釋器鎖在Python中飽受詬病,但是它確實為Python內存處理提供了方便。

什么是全局解釋器鎖

Python通過引用計數的方法來管理內存,每一個內存對象都會有一個引用計數,如果一個對象的引用計數變為0,那么該對象所占用的內存就會被釋放。比如

import sys

a = []

b = a

sys.getrefcount(a)

## 3

在上述代碼中,空列表對象在內存中被引用了3次,即分別被a和b引用,同時被sys.getrefcount()調用。

但是,如果一個對象同時被多個線程來引用,那么引用計數可能同時增加或減少,每個線程按照自己的方式進行計數,對象在整個內存中的引用變得十分混亂,很容易造成內存泄漏或者其他很多不可預見的Bug。一個解決辦法給就是每個線程都給引用計數加一個鎖,阻止別人修改,不過這樣會造成鎖死現象(比如一個對象有多個鎖時),另外,大量的資源會浪費在加鎖解鎖的過程了,嚴重拖慢了程序運行速度。

這個時候,就需要一個統一來管理引用計數的機制,以確保對象引用計數準確、安全。全局解釋器鎖就是用來處理這種情況的。它既避免了不同線程帶來的引用計數混亂,又避免了過多線程鎖帶來的死鎖和運行效率低的問題。

雖然全局解釋器鎖解決了對象引用計數的問題,但隨之而來的是,很多CPU密集型任務在全局解釋器鎖的作用下,實際上變成了單線程,不能充分發揮CPU的算力,影響程序速度。

全局解釋器鎖并不是Python獨有的,其他一些語言,比如Ruby也存在全局解釋器鎖。還有一些語言沒有使用引用計數的方式來管理內容,而是使用垃圾回收機制(GC)來管理內存。雖然這樣避免了全局解釋器鎖,但是在單線程處理上,GC并不占有優勢。

為什么Python選擇全局解釋器鎖

Python在設計之初,就選擇了全局解釋器鎖用來管理內存引用計數,在當時,操作系統還沒有線程的概念,所以全局解釋器鎖并沒有帶了弊端,反而給開發者帶來了很多方便。

很多Python的擴展都是使用C語言庫來編寫的,這些C編寫的擴展需要全局解釋器鎖來確保線程的內存安全。即便是有些C語言庫內存處理上不是很安全,那么在Python中全局解釋器鎖的作用下,也能很好的發揮作用。

所以,全局解釋器鎖對早期使用CPython做解釋器的開發者來說,解決了很多內存管理的問題。

全局解釋器鎖對多線程的影響

首先我們應該區分不同性質的任務,有一些是CPU密集型的任務,有一些是I/O密集型的任務。

CPU密集型的任務在最大程度上使用了CPU,比如數學矩陣的計算、圖像處理、文件解壓縮等。

I/O密集型任務在需要花費很多時間來等待信息的輸入和輸出(讀寫),比如從網址下載內容,大量訪問磁盤進行讀寫等。

如果是CPU密集型任務,比如下面我們進行倒計時,使用單線程:

# 單線程

import time

from threading import Thread

COUNT = 50000000

def countdown(n):

while n>0:

n -= 1

start = time.time()

countdown(COUNT)

end = time.time()

print('Time taken in seconds -', end - start)

# Time taken in seconds - 6.20024037361145

最后倒計時完成,一共用了6.2秒

使用多線程

# 使用多線程

import time

from threading import Thread

COUNT = 50000000

def countdown(n):

while n>0:

n -= 1

t1 = Thread(target=countdown, args=(COUNT//2,))

t2 = Thread(target=countdown, args=(COUNT//2,))

start = time.time()

t1.start()

t2.start()

t1.join()

t2.join()

end = time.time()

print('Time taken in seconds -', end - start)

# Time taken in seconds - 6.924342632293701

最后用了6.9秒!

可以看出來,對于這個CPU密集型的任務,多線程使用的時間竟然比單線程還多,使用多線程并沒有達到我們縮短運行時間的目的。這就是全局解釋器鎖帶來的問題。但是如果是I/O密集型的任務,全局解釋器鎖就不會再有這種影響,各個線程在等待I/O的時候可以共享鎖。

為什么全局解釋器鎖還保留在Python中

首先全局解釋器鎖一直在Python中使用,如果在某個版本中移除了全局解釋器鎖,會帶來各種兼容性問題,尤其是對于Python這種有大量開發者的編程語言來說,稍微一點變動都會帶來巨大的影響。另外,很多C語言編寫的擴展嚴重依賴于局解釋器鎖。況且,如果移除了全局解釋器鎖,那么又可能會造成單線程或者I/O多線程處理速度的下降。

當Python從2.0升級到3.0的大版本升級時,實際上是有機遇改變全局解釋器鎖的。但是這使得Python3在處理單線程或者I/O多線程時,比Python2還慢!所以Python3中依舊保留了全局解釋器鎖。當然,在Python3中,對全局解釋器鎖進行了修改和優化,即減少I/O所線程使用全局解釋器鎖的機會,把更多的時間和機會留給CPU密集型多線程任務。另外,如果一個線程持續使用全局解釋器鎖一段時間后,程序會強制其釋放全局解釋器鎖,當然如果沒有其他線程請求使用全局解釋器鎖,那么該線程還可以繼續使用全局解釋器鎖。

我們應該應對全局解釋器鎖

既然全局解釋器鎖帶來一些問題,那么我們怎么來解決這些問題?這兒我們要說兩個不同的概念:

多進程(multi-processing) 和多線程(multi-threading):

多進程是各個并行任務之間“不使用“共同的內存空間;而多線程的各個并行任務”使用“共同的內存空間。

1)多進程

優點:獨立內存空間;實現代碼直觀簡單;充分利用多核多CPU;避免全局解釋器鎖的限制;

缺點:無法實現對象和內容共享;需要較大的內存空間

2)多線程

優點:輕量,需要的額外內存較小;共享內存,方便訪問;對于CPython解釋器,可以通過全局解釋器鎖使用C擴展;適合I/O密集型任務

缺點:全局解釋器鎖的限制;并行任務不能殺掉;實現代碼較為復雜

我們通過多進程的形式來實現上面例子中的倒計時,

from multiprocessing import Pool

import time

COUNT = 50000000

def countdown(n):

while n>0:

n -= 1

if __name__ == '__main__':

pool = Pool(processes=2)

start = time.time()

r1 = pool.apply_async(countdown, [COUNT//2])

r2 = pool.apply_async(countdown, [COUNT//2])

pool.close()

pool.join()

end = time.time()

print('Time taken in seconds -', end - start)

# Time taken in seconds - 4.060242414474487

通過多進程只用了4秒,速度大大加快了。

另外,全局解釋器鎖存在于Cpython的解釋器中,如果你使用其他的Python解釋器,比如Jython(使用Java編寫), IronPython(使用C#編寫)和PyPy(使用Python編寫),可能不會遇到全局解釋器鎖的情況。

總結

全局解釋器鎖在CPython中,限制了CPU密集型的多線程處理任務。遇到CPU密集型的多線程處理任務時,我們盡量使用多進程的方式來處理(multiprocessing)。

=====》》》《《《《======

擴展:在R、Python和shell中如何實現多進程處理:

資料來源:

總結

以上是生活随笔為你收集整理的c语言的锁和Python锁,Python中全局解释器锁、多线程和多进程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。