PyCon China · 2019
Open source contributor, werkzeug, requests, doom-emacs, etc.
What is GIL?
# single_threaded.py
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)
$ python single_threaded.py
Time taken in seconds - 6.20024037361145
# multi_threaded.py
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)
$ python multi_threaded.py
Time taken in seconds - 6.924342632293701
$ python multi_threaded.py
Time taken in seconds - 6.924342632293701
$ python single_threaded.py
Time taken in seconds - 6.20024037361145
L.append(x)
L1.extend(L2)
x = L[i]
x = L.pop()
L1[i:j] = L2
L.sort()
x = y
x.field = y
D[x] = y
D1.update(D2)
D.keys()
i = i+1
L.append(L[-1])
L[i] = L[j]
D[x] = D[x] + 1
Safe
Not Safe
Python Source Code (.py files)
Python Interpreter
Result
Python Source Code (.py files)
Result
Compiler
Bytecode
Virtual Machine
Python Interpreter
Library Modules
Python Source Code (.py files)
Result
Compiler
Bytecode
Virtual Machine
Python Interpreter
Library Modules
GIL
Is `number += 1` thread safe?
from dis import dis
dis(lambda x: x+1)
1 0 LOAD_FAST 0 (x)
2 LOAD_CONST 1 (1)
4 BINARY_ADD
6 RETURN_VALUE
GIL
GIL
GIL
GIL
How GIL works?
Thread 1
Thread 2
I/O
Release GIL
Acquire GIL
I/O
Release GIL
Acquire GIL
I/O
Release GIL
Acquire GIL
David Beazley Understand GIL
OS
Thread 1
Thread 2
Check
Release GIL
Acquire GIL
Check
Release GIL
Acquire GIL
Release GIL
Acquire GIL
Check
run 100 ticks
run 100 ticks
run 100 ticks
run 100 ticks
David Beazley Understand GIL
OS
David Beazley Understand GIL
Thread 1
Thread 2
David Beazley Understand GIL
run 100 ticks
OS
Release GIL
Acquire GIL
run 100 ticks
Release GIL
Acquire GIL
Release GIL
Acquire GIL
check
check
check
run 100 ticks
Idle
run 100 ticks
CPU 1
CPU 1
Thread 1
Thread 2
David Beazley Understand GIL
run 100 ticks
OS
Release GIL
Acquire GIL
run 100 ticks
Release GIL
Acquire GIL
Release GIL
Acquire GIL
check
check
check
run 100 ticks
run 100 ticks
CPU 1
CPU 2
Wake
Acquire GIL
(fails)
Wake
Acquire GIL
(fails)
Wake
Acquire GIL
(success)
Remove GIL?
I'd welcome a set of patches into Py3k only if the performance for a single-threaded program (and for a multi-threaded but I/O-bound program) does not decrease.
-- Guido van Rossum
Use C extensions!
The Future
Process
Interpreter
Interpreter
GIL
GIL
Thread
Thread
Thread
Support for other basic types (e.g. bool, float) will be added later
Process
Interpreter
Interpreter
GIL
GIL
Thread
Thread
Thread
Channel
(请备注公司/学校 + 姓名)