## 一、介绍

``````import time, threading

# 新线程执行的代码:
def loop():
n = 0
while n < 5:
n = n + 1
time.sleep(1)

t.start()
t.join()
``````

``````thread MainThread is running...
``````

## 二、Lock

``````import time, threading

# 假定这是你的银行存款:
balance = 0

def change_it(n):
# 先存后取，结果应该为0:
global balance
balance = balance + n
balance = balance - n

for i in range(100000):
change_it(n)

t1.start()
t2.start()
t1.join()
t2.join()
print(balance)
``````

``````balance = balance + n
``````

• 计算 balance + n，存入临时变量中
• 将临时变量的值赋给 balance

``````x = balance + n
balance = x
``````

``````初始值 balance = 0

t1: x1 = balance + 5 # x1 = 0 + 5 = 5
t1: balance = x1     # balance = 5
t1: x1 = balance - 5 # x1 = 5 - 5 = 0
t1: balance = x1     # balance = 0

t2: x2 = balance + 8 # x2 = 0 + 8 = 8
t2: balance = x2     # balance = 8
t2: x2 = balance - 8 # x2 = 8 - 8 = 0
t2: balance = x2     # balance = 0

``````

``````初始值 balance = 0

t1: x1 = balance + 5  # x1 = 0 + 5 = 5

t2: x2 = balance + 8  # x2 = 0 + 8 = 8
t2: balance = x2      # balance = 8

t1: balance = x1      # balance = 5
t1: x1 = balance - 5  # x1 = 5 - 5 = 0
t1: balance = x1      # balance = 0

t2: x2 = balance - 8  # x2 = 0 - 8 = -8
t2: balance = x2   # balance = -8

``````

``````balance = 0

for i in range(100000):
# 先要获取锁:
lock.acquire()
try:
# 放心地改吧:
change_it(n)
finally:
# 改完了一定要释放锁:
lock.release()
``````

## 三、多核 CPU

``````import threading, multiprocessing

def loop():
x = 0
while True:
x = x ^ 1

for i in range(multiprocessing.cpu_count()):
t.start()
``````

GIL 是 Python 解释器设计的历史遗留问题，通常我们用的解释器是官方实现的CPython，要真正利用多核，除非重写一个不带GIL的解释器。

## 四、小结

Python 解释器由于设计时有 GIL 全局锁，导致了多线程无法利用多核。多线程的并发在 Python 中就是一个美丽的梦。

JSmiles

2249 文章
47 评论
51658 人气