diff --git a/python-gil/README.md b/python-gil/README.md new file mode 100644 index 0000000000..7014696725 --- /dev/null +++ b/python-gil/README.md @@ -0,0 +1,30 @@ +# What Is the Python Global Interpreter Lock (GIL)? + +This folder provides the code examples for the Real Python tutorial [What Is the Python Global Interpreter Lock (GIL)?](https://realpython.com/python-gil/). + +The tutorial shows some of its examples at the REPL. Those are provided here as +runnable scripts that print the values the tutorial discusses: + +| Script | Tutorial section | +| --- | --- | +| `reference_counting.py` | What Problem Did the GIL Solve for Python? | +| `single_threaded.py` | The Impact on Multi-Threaded Python Programs | +| `multi_threaded.py` | The Impact on Multi-Threaded Python Programs | +| `switch_interval.py` | Why Wasn't It Removed in Python 3? | +| `multiprocess.py` | How to Deal With Python's GIL | + +## Running the Examples + +The examples only use the Python standard library, so there's nothing to +install. Create and activate a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/), +then run any of the scripts: + +```sh +$ python -m venv venv/ +$ source venv/bin/activate +(venv) $ python single_threaded.py +``` + +The timings printed by `single_threaded.py`, `multi_threaded.py`, and +`multiprocess.py` depend on your machine, so they won't match the numbers in +the tutorial exactly. What matters is how they compare to each other. diff --git a/python-gil/multi_threaded.py b/python-gil/multi_threaded.py new file mode 100644 index 0000000000..b336169883 --- /dev/null +++ b/python-gil/multi_threaded.py @@ -0,0 +1,22 @@ +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) diff --git a/python-gil/multiprocess.py b/python-gil/multiprocess.py new file mode 100644 index 0000000000..8e3f220666 --- /dev/null +++ b/python-gil/multiprocess.py @@ -0,0 +1,20 @@ +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) diff --git a/python-gil/reference_counting.py b/python-gil/reference_counting.py new file mode 100644 index 0000000000..62067952f5 --- /dev/null +++ b/python-gil/reference_counting.py @@ -0,0 +1,5 @@ +import sys + +a = [] +b = a +print(sys.getrefcount(a)) diff --git a/python-gil/single_threaded.py b/python-gil/single_threaded.py new file mode 100644 index 0000000000..4b4cbe6c33 --- /dev/null +++ b/python-gil/single_threaded.py @@ -0,0 +1,15 @@ +import time + +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) diff --git a/python-gil/switch_interval.py b/python-gil/switch_interval.py new file mode 100644 index 0000000000..26f5f5c93b --- /dev/null +++ b/python-gil/switch_interval.py @@ -0,0 +1,4 @@ +import sys + +# The switch interval is set to 5 milliseconds: +print(sys.getswitchinterval())