python中的多线程

python代码的执行是由python虚拟机进行控制的。尽管python解释器中可以运行多个线程,但是在任意给定时刻只有一个线程会被解释器执行。

python虚拟机的访问是由全局解释器锁(GIL)控制的。这个锁就是用来保证同时只能有一个线程运行的。因此,在 python中无法通过多线程来利用多个 CPU同时处理任务,以达到应用加速的目的。下面通过两个测试程序可以验证这个问题。

我的处理器有 8个核,因此在多线程测试中一共创建 8个线程来处理任务,这里的任务特指:使用递归求解斐波拉契数。

多线程版本代码:

#!/usr/bin/env python

import threading
from time import time

def foo(n):
	if n < 2:
		return 1
	return foo(n - 2) + foo(n - 1)

def main():
	threads = []
	n_process = 8
	n = 36

	for i in range(0, n_process):
		t = threading.Thread(target=foo, args=(n,))
		threads.append(t)

	start = time()
	for i in range(0, n_process):
		threads[i].start()

	for i in range(0, n_process):
		threads[i].join()

	end = time()
	print("start: %f, end: %f, cost: %f" % (start, end, end - start))


if __name__ == "__main__":
	main()

运行时间:

$ python3 ./python/multi_thread/main.py
start: 1687413176.686146, end: 1687413199.358464, cost: 22.672318

单线程版本代码:

#!/usr/bin/env python

from time import time

def foo(n):
	if n < 2:
		return 1
	return foo(n - 2) + foo(n - 1)

def main():
	n_process = 8
	n = 36

	start = time()
	for i in range(0, n_process):
		foo(n)

	end = time()
	print("start: %f, end: %f, cost: %f" % (start, end, end - start))


if __name__ == "__main__":
	main()

运行时间:

$ python3 ./python/multi_thread/main2.py
start: 1687413202.103315, end: 1687413223.906954, cost: 21.803639

从上面的例子可以看到,由于 python虚拟机是单线程(GIL)的原因,对于计算密集型任务,多线程无法起到应用加速的目的,只有程序在执行I/O密集型的任务时才能更好地发挥 python多线程的并发行(I/O释放了GIL,可以允许更多的并发)。对于计算密集型任务,为了实现更好的并行性,需要使用多进程,以便让 CPU的其他核来同时处理任务。

参考资料:
Python核心编程:第3版 /(美)春(Chun, W.)著;孙波翔,李斌,李晗译.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值