GIL: Global Interpreter Lock 全局解释器锁.
每个 python process 都只创建唯一一个关键资源 GIL,当一个 thread 运行时,它必须获取此 GIL,运行结束再释放。
由于 GIL 唯一,因此任何时候,一个 process 中都不能有两个 thread 同时运行,一次只能运行一个 thread,这是由 python 的实现决定的,python 不善于以并行方式运行代码。
虽然 python 不支持两个 thread 并行执行,但是当程序需要等待时,使用线thread 可以缩短等待时间。
如果所有的 thread 都只是使用CPU,使用 thread 没有意义,因为时间不仅不会缩短,反而会因为 thread 频繁获取和释放 GIL 增加运行时间。
要创建线程,要先导入 threading
模块:
from threading import Thread
my_thread = Thread(target=my_func_name)
my_thread.start()
下面的程序有3个 thread: 主线程 main thread 以及 thread 1, thread 2
ask_user()
函数等待用户输入并输出,complex_calculation()
运行一项需要时间的计算:
import time
from threading import Thread
def ask_user():
start = time.time()
user_input = input("Enter your name: ")
greet = f"Hello, {user_input}"
print(greet)
print(f'ask_user, {time.time() - start}')
def complex_calculation():
start = time.time()
print('Started calculating...')
[x**2 for x in range(20000000)]
print(f'complex_calculation, {time.time() - start}')
start = time.time()
ask_user()
complex_calculation()
print(f'Single thread total time: {time.time() - start}')
thread1 = Thread(target=complex_calculation)
thread2 = Thread(target=ask_user)
start = time.time()
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print(f"Two threads total time: {time.time() - start} ")
输出如下:
Enter your name: user
Hello, user
ask_user, 2.0858802795410156
Started calculating...
complex_calculation, 3.8278822898864746
Single thread total time: 5.914762496948242
Started calculating...
Enter your name: user
Hello, user
ask_user, 1.4944937229156494
complex_calculation, 3.8242249488830566
Two threads total time: 3.8242249488830566
Process finished with exit code 0
可见,使用线程,运行时间明显缩短,所用时间对比:
Single thread total time: 5.914762496948242
Two threads total time: 3.8242249488830566
join()
方法使主线程等待,直到 thread1
,thread2
运行结束。