淺談Python的GIL機(jī)制

python多線程

實(shí)驗(yàn):

  • 開(kāi)啟兩個(gè)線程
  • 一個(gè)線程sleep 4s 死循環(huán)打印
  • 另外一個(gè)線程sleep 1s 死循環(huán)打印

結(jié)果:會(huì)正常的交替運(yùn)行
結(jié)論:一個(gè)線程被阻塞的時(shí)候,CPU會(huì)被釋放,然后另外一個(gè)線程被執(zhí)行。。

使用python為例子

參考資料:

[http://zhuoqiang.me/python-thread-gil-and-ctypes.html](http://zhuoqiang.me/python-thread-gil-and-ctypes.html)

所有Thread的PID都與主程序相同,而每個(gè)Process都有一個(gè)不同的PID要

單線程

使用如下的代碼:

#!coding=utf8
"""
使用多核
"""
import sys
sys.path.append('../../')

if __name__ == "__main__":
   print("start run here")
   while True:
       a = 4 / 34.0
   print('end run here')

開(kāi)始運(yùn)行前


image.png

使用
python expmultiprocess.py

開(kāi)始運(yùn)行后


image.png

可以看出,占滿一個(gè)核心的所有資源了。

主線程外再開(kāi)啟一個(gè)線程


image.png

可以看出:

  1. 有兩個(gè)進(jìn)程號(hào)。PID是不一樣的。
  2. 所有的CPU并沒(méi)有占満

因?yàn)镚IL的原因:

  1. 單進(jìn)程單線程可以占用并占滿一個(gè)核心。
  2. 單進(jìn)程多線程可以占用多核心但無(wú)法占滿,只會(huì)分時(shí)復(fù)用。

GIL全局解釋器鎖

參考資料:http://zhuoqiang.me/python-thread-gil-and-ctypes.html

GIL 的全程為 Global Interpreter Lock ,意即全局解釋器鎖。
在 Python 語(yǔ)言的主流實(shí)現(xiàn) CPython 中,GIL 是一個(gè)貨真價(jià)實(shí)的全局線程鎖,在解釋器解釋執(zhí)行任何 Python 代碼時(shí),都需要先獲得這把鎖才行,在遇到 I/O 操作時(shí)會(huì)釋放這把鎖。如果是純計(jì)算的程序,沒(méi)有 I/O 操作,解釋器會(huì)每隔 100 次操作就釋放這把鎖,讓別的線程有機(jī)會(huì)執(zhí)行,這個(gè)次數(shù)可以通過(guò)sys.setcheckinterval。
所以雖然 CPython 的線程庫(kù)直接封裝操作系統(tǒng)的原生線程,但 CPython 進(jìn)程做為一個(gè)整體,同一時(shí)間只會(huì)有一個(gè)獲得了 GIL 的線程在跑,其它的線程都處于等待狀態(tài)等著 GIL 的釋放。這也就解釋了我們上面的實(shí)驗(yàn)結(jié)果:雖然有兩個(gè)死循環(huán)的線程,而且有兩個(gè)物理 CPU 內(nèi)核,但因?yàn)?GIL 的限制,兩個(gè)線程只是做著分時(shí)切換,總的 CPU 占用率還略低于 50%。

以java為例子

Java的多線程是完全可以把多個(gè)核心跑滿的。

package com.data;

public class ThreadDemo extends Thread {

public ThreadDemo() {

}

public void run() {

while (true) {

continue;

}

}

public static void main(String[] args) {

try {

ThreadDemo h1 = new ThreadDemo();

h1.start();

ThreadDemo h2 = new ThreadDemo();

h2.start();

ThreadDemo h3 = new ThreadDemo();

h3.start();

h1.join();

h2.join();

h3.join();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

里面開(kāi)啟了三個(gè)線程,然后CPU三個(gè)核心都跑滿了。

image.png

使用pyspark運(yùn)行

Python可以通過(guò)一些專(zhuān)門(mén)的數(shù)據(jù)處理框架來(lái)實(shí)現(xiàn)高效利用CPU,直接所有的核心都利用起來(lái)了。不用自己再去寫(xiě)并行計(jì)算的內(nèi)容結(jié)構(gòu)了。

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一. 操作系統(tǒng)概念 操作系統(tǒng)位于底層硬件與應(yīng)用軟件之間的一層.工作方式: 向下管理硬件,向上提供接口.操作系統(tǒng)進(jìn)行...
    月亮是我踢彎得閱讀 6,157評(píng)論 3 28
  • 必備的理論基礎(chǔ) 1.操作系統(tǒng)作用: 隱藏丑陋復(fù)雜的硬件接口,提供良好的抽象接口。 管理調(diào)度進(jìn)程,并將多個(gè)進(jìn)程對(duì)硬件...
    drfung閱讀 3,756評(píng)論 0 5
  • 轉(zhuǎn)一篇關(guān)于Python GIL的文章。歸納一下,CPU的大規(guī)模電路設(shè)計(jì)基本已經(jīng)到了物理意義的盡頭,所有廠商們都開(kāi)始...
    SeanCheney閱讀 11,326評(píng)論 0 12
  • 前言:博主在剛接觸Python的時(shí)候時(shí)常聽(tīng)到GIL這個(gè)詞,并且發(fā)現(xiàn)這個(gè)詞經(jīng)常和Python無(wú)法高效的實(shí)現(xiàn)多線程劃上...
    whypro閱讀 1,262評(píng)論 0 1
  • 早上醒來(lái)看看那初生的驕陽(yáng), 心靈被朝氣滋養(yǎng)。 忘卻了昨夜難眠的煩惱, 給自己打氣, 今日是完美的一天! 我能行! ...
    醉夢(mèng)客閱讀 182評(píng)論 0 3

友情鏈接更多精彩內(nèi)容