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

歡迎訪問 生活随笔!

生活随笔

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

python

python gil_Python GIL(Global Interpreter Lock)

發(fā)布時間:2025/4/5 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python gil_Python GIL(Global Interpreter Lock) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、GIL介紹

GIL本質(zhì)就是一把互斥鎖,既然是互斥鎖,所有互斥鎖的本質(zhì)都一樣,都是將并發(fā)運行變成串行,以此來控制同一時間內(nèi)共享數(shù)據(jù)只能被一個任務(wù)所修改,進而保證數(shù)據(jù)安全。

可以肯定的一點是:保護不同的數(shù)據(jù)的安全,就應(yīng)該加不同的鎖。

要了解GIL,首先確定一點:每次執(zhí)行python程序,都會產(chǎn)生一個獨立的進程。例如python test.py,python aaa.py,python bbb.py會產(chǎn)生3個不同的python進程

在一個python的進程內(nèi),不僅有test.py的主線程或者由該主線程開啟的其他線程,還有解釋器開啟的垃圾回收等解釋器級別的線程,總之,所有線程都運行在這一個進程內(nèi)。

1、所有數(shù)據(jù)都是共享的

其中代碼作為一種數(shù)據(jù)也是被所有線程共享的(test.py的所有代碼以及Cpython解釋器的所有代碼)

2、所有線程的任務(wù),都需要將任務(wù)的代碼當做參數(shù)傳給解釋器的代碼去執(zhí)行,即所有的線程要想運行自己的任務(wù),首先需要解決的是能夠訪問到解釋器的代碼

綜上:

如果多個線程的target=work,那么執(zhí)行流程是

多個線程先訪問到解釋器的代碼,即拿到執(zhí)行權(quán)限,然后將target的代碼交給解釋器的代碼去執(zhí)行

解釋器的代碼是所有線程共享的,所以垃圾回收線程也可能訪問到解釋器的代碼而去執(zhí)行,這就導致了一個問題:

對于同一個數(shù)據(jù)100,可能線程1執(zhí)行x=100的同時,而垃圾回收執(zhí)行的是回收100的操作,解決這種問題沒有什么高明的方法?

就是加鎖處理,如下圖的GIL,保證python解釋器同一時間只能執(zhí)行一個任務(wù)的代碼

二、GIL與Lock

GIL保護的是解釋器級的數(shù)據(jù),保護用戶自己的數(shù)據(jù)則需要自己加鎖處理,如下圖

三、GIL與多線程

有了GIL的存在,同一時刻同一進程中只有一個線程被執(zhí)行

進程可以利用多核,但是開銷大,而python的多線程開銷小,但卻無法利用多核優(yōu)勢,要解決這個問題,我們需要在幾個點上達成一致:

1. cpu到底是用來做計算的,還是用來做I/O的?

2. 多cpu,意味著可以有多個核并行完成計算,所以多核提升的是計算性能

3. 每個cpu一旦遇到I/O阻塞,仍然需要等待,所以多核對I/O操作沒什么用處

一個工人相當于cpu,此時計算相當于工人在干活,I/O阻塞相當于為工人干活提供所需原材料的過程,工人干活的過程中如果沒有原材料了,則工人干活的過程需要停止,直到等待原材料的到來。

如果你的工廠干的大多數(shù)任務(wù)都要有準備原材料的過程(I/O密集型),那么你有再多的工人,意義也不大,還不如一個人,在等材料的過程中讓工人去干別的活,

反過來講,如果你的工廠原材料都齊全,那當然是工人越多,效率越高

結(jié)論:

對計算來說,cpu越多越好,但是對于I/O來說,再多的cpu也沒用

當然對運行一個程序來說,隨著cpu的增多執(zhí)行效率肯定會有所提高(不管提高幅度多大,總會有所提高),這是因為一個程序基本上不會是純計算或者純I/O,所以我們只能相對的去看一個程序到底是計算密集型還是I/O密集型,從而進一步分析python的多線程到底有無用武之地。

假設(shè)一種情況:

現(xiàn)在有四個任務(wù)需要處理,處理方式是要有并發(fā)的效果,解決方案可以是:

方案一:開啟四個進程

方案二:一個進程下,開啟四個線程

單核情況下,分析結(jié)果:

如果四個任務(wù)是計算密集型,沒有多核來并行計算,方案一徒增了創(chuàng)建進程的開銷,方案二勝

如果四個任務(wù)是I/O密集型,方案一創(chuàng)建進程的開銷大,且進程的切換速度遠不如線程,方案二勝

多核情況下,分析結(jié)果:

如果四個任務(wù)是計算密集型,多核意味著并行計算,在python中一個進程中同一時刻只有一個線程執(zhí)行用不上多核,方案一勝

如果四個任務(wù)是I/O密集型,再多的核也解決不了I/O問題,方案二勝

結(jié)論:

現(xiàn)在的計算機基本上都是多核,python對于計算密集型的任務(wù)開多線程的效率并不能帶來多大性能上的提升,甚至不如串行(沒有大量切換)

但是,對于IO密集型的任務(wù)效率還是有顯著提升的。

四、多線程性能測試

1、計算密集型:多進程效率高

from multiprocessing import Process

from threading import Thread

import os,time

def work():

res=0

for i in range(100000000):

res*=i

l=[]

print(os.cpu_count()) #本機為4核

start=time.time()

for i in range(4):

# p=Process(target=work) #耗時18s多

p=Thread(target=work) #耗時26s多

l.append(p)

p.start()

for p in l:

p.join()

stop=time.time()

print('run time is %s' %(stop-start))

2、i/o密集型:多線程效率高

from multiprocessing import Process

from threading import Thread

import threading

import os,time

def work():

time.sleep(2)

print('===>')

l=[]

print(os.cpu_count()) #本機為4核

start=time.time()

for i in range(400):

p=Process(target=work) #耗時4s多,大部分時間耗費在創(chuàng)建進程上

# p=Thread(target=work) #耗時2s多

l.append(p)

p.start()

for p in l:

p.join()

stop=time.time()

print('run time is %s' %(stop-start))

應(yīng)用:

多線程用于IO密集型,如socket,爬蟲,web

多進程用于計算密集型,如金融分析

總結(jié)

以上是生活随笔為你收集整理的python gil_Python GIL(Global Interpreter Lock)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。