いろは3010814 views
英語613639 views
高校化学2924392 views
ヒストリア290598 views
中学理科1630641 views
教育149510 views
高校国語788336 views
小学算数1200427 views
高校倫理1440106 views
数学講師2886227 views
Help
Tools
NewsSpreadsheetCalendarSlidesTier ListPen ToolIllustrationCrayonPixel ArtASCII ArtPerspectiveEndless StairsGraphMind MapER DiagramFamily TreeMemeCurved TextImage EditorMosaicRetro FilterPencil SketchOCR/HighlighterMakeup EditorFaviconVideo TrimmerScrolling VideoVideo TitleColor PickerColor ExtractorBonfireFireworksWater RippleWater SplashBreaking GlassWood GrainMarble TextureCSS ButtonIcon MakerBar ChartGrouped Bar ChartStacked Bar ChartPie ChartLine ChartArea ChartStacked Area ChartScatter Plot3D Bar Chart3D Pie ChartBar Chart RaceBubble ChartPopulation PyramidPictogramEarningsCandlestick ChartInvestment RiskMortgage SimulatorCalculatorMatrix CalculatorFunction GraphPolynomial ExpansionVenn DiagramField VisualizerRubik's Cube Group TheoryTraveling SalesmanVoronoi and DelaunayFractalColumn ArithmeticDraw Math FiguresArithmetic AnimationArithmetic Word ProblemsCounting with Tree DiagramsCube NetsCross SectionsMotion PathMechanicsWavesLight and LensesThermodynamicsHow Semiconductors WorkMolecular StructuresAtomic OrbitalsElectrochemical CellsChemical EquilibriumCrystal LatticesBuffer pHComplex IonsDNA Double HelixCell DivisionMembrane ChannelsNerve ImpulseRock ClassificationWeatherConstellationsSolar and Lunar Eclipses3D ModelingFloor PlanSeismic StructuresIntersection TurnMaglevCooking AnimationOrigamiLive Viewer CountGeoJSON MapRailway MapPopulation MapCrime MapLand Price MapSchool MapShrine and Castle MapHouse of Representatives MapWord MapSolitaireReversiHakoiri MusumeChessHamburgerRippleSlide Puzzle MakerNeon PinballNovel MakerJapanese Typing PracticePiano Score EditorMusic Theory

English

Python の GIL とは

GIL(Global Interpreter Lock)は、Python インタプリタが一度に1つのスレッドだけが Python バイトコードを実行することを保証するロック機構です。マルチスレッドプログラミングを理解する上で、GIL の存在は非常に重要です。

GIL とは何か

GIL は CPython(標準の Python 実装)に存在するグローバルなロックです。このロックにより、複数のスレッドがあっても、実際に Python コードを実行できるのは常に1つのスレッドだけです。

import threading
import time

counter = 0

def increment():
    global counter
    for _ in range(1000000):
        counter += 1

t1 = threading.Thread(target=increment)
t2 = threading.Thread(target=increment)

start = time.time()
t1.start()
t2.start()
t1.join()
t2.join()

print(f"結果: {counter}")  # 2000000 にならないことがある
print(f"時間: {time.time() - start:.2f}秒")

なぜ GIL が存在するのか

GIL は Python のメモリ管理を単純化するために導入されました。

参照カウント

Python はオブジェクトの参照カウントでメモリを管理している。GIL がないと、複数スレッドが同時に参照カウントを変更してメモリ破損が起きる可能性がある。

C 拡張の安全性

多くの C 拡張モジュールは GIL を前提に書かれている。GIL があることで、スレッドセーフでない C コードも安全に呼び出せる。

GIL の影響

CPU バウンド処理

複数スレッドでも並列実行されない。マルチスレッドの恩恵を受けにくい。

I/O バウンド処理

I/O 待ち中は GIL が解放される。マルチスレッドの恩恵を受けられる。

CPU バウンドな処理では、マルチスレッドにしても速くならないことがあります。

import threading
import time

def cpu_bound():
    total = 0
    for i in range(10000000):
        total += i
    return total

# シングルスレッド
start = time.time()
cpu_bound()
cpu_bound()
print(f"シングルスレッド: {time.time() - start:.2f}秒")

# マルチスレッド
start = time.time()
t1 = threading.Thread(target=cpu_bound)
t2 = threading.Thread(target=cpu_bound)
t1.start()
t2.start()
t1.join()
t2.join()
print(f"マルチスレッド: {time.time() - start:.2f}秒")
# ほぼ同じか、むしろ遅いことがある

I/O 処理では GIL が解放される

ファイル I/O やネットワーク通信などの I/O 操作中は、GIL が一時的に解放されます。そのため、I/O バウンドな処理ではマルチスレッドが効果的です。

import threading
import time

def io_bound():
    time.sleep(1)  # I/O をシミュレート

# シングルスレッド
start = time.time()
io_bound()
io_bound()
print(f"シングルスレッド: {time.time() - start:.2f}秒")  # 約2秒

# マルチスレッド
start = time.time()
t1 = threading.Thread(target=io_bound)
t2 = threading.Thread(target=io_bound)
t1.start()
t2.start()
t1.join()
t2.join()
print(f"マルチスレッド: {time.time() - start:.2f}秒")  # 約1秒

GIL を回避する方法

CPU バウンドな処理を並列化したい場合の選択肢があります。

multiprocessing

プロセスごとに独立した GIL を持つため、真の並列実行が可能。

C 拡張 / NumPy

NumPy などの C 拡張は、計算中に GIL を解放することがある。

別の Python 実装

Jython や IronPython には GIL がない。

Python でマルチスレッドを使う際は、GIL の特性を理解して、I/O バウンドな処理に活用するのが効果的です。