CPython在CPU密集型应用下的并发

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CPython在CPU密集型应用下的并发相关的知识,希望对你有一定的参考价值。

Python是解释型语言,根据不同的底层协议有很多种版本,最常见的是基于C的Cpython,默认情况下我们所说的Python就是Cpython。

Python的GIL(global interpreter lock):

  用于解决多线程之间的数据完整性和状态同步而存在,使得不管线程分布在多少个CPU上,解释器同一时刻只允许1个线程运行。

所以Python是thread_safe的。这样其实Python就几乎只能进行单线程编程了。

 

CPU密集型应用:(频繁计算)

从1开始累加,到1亿
1 def foo():
2     num = 0
3     for i in range(100000001):
4         num += i

现在进行一个任务,完成三次函数foo()的运行,计算总耗时,给出四种方案

1、单线程,1,2,3,4串行

2、多线程,1,2,3,4并行

3、单进程,1,2,3,4串行

4、多进程,1,2,3,4并行

通过实验验证在CPU秘籍应用下Python并发的最佳实现方式

测试电脑CPU:

intel_I7-4700(4核8线程)

方案1;

 1 if __name__ == "__main__":
 2     t_list = []
 3     start_time = time.time()
 4     for i in range(5):
 5         i = threading.Thread(target=foo)
 6         t_list.append(i)
 7         i.start()
 8         i.join()
 9     end_time = time.time()
10     print("Totally time:{}".format(end_time-start_time))

 

 

方案2;

 1 if __name__ == "__main__":
 2     t_list = []
 3     start_time = time.time()
 4     for i in range(5):
 5         i = threading.Thread(target=foo)
 6         t_list.append(i)
 7         i.start()
 8     for i in t_list:
 9         i.join()
10     end_time = time.time()
11     print("Totally time:{}".format(end_time-start_time))

 

 

方案3;

 1 if __name__ == "__main__":
 2     p_list = []
 3     start_time = time.time()
 4     for i in range(5):
 5         i = multiprocessing.Process(target=foo)
 6         p_list.append(i)
 7         i.start()
 8         i.join()
 9     end_time = time.time()
10     print("Totally time:{}".format(end_time-start_time))

 

 

方案4;

 1 if __name__ == "__main__":
 2     p_list = []
 3     start_time = time.time()
 4     for i in range(5):
 5         i = multiprocessing.Process(target=foo)
 6         p_list.append(i)
 7         i.start()
 8     for i in p_list:
 9         i.join()
10     end_time = time.time()
11     print("Totally time:{}".format(end_time-start_time))

 

 

方案与实践的对应:

方案1:——42.97582244873047

方案2:——44.63868308067322

方案3:——45.94909477233887

方案4:——15.7623131275177

 

总结:

这里multi_thread的效率竟然低于single_thread!所以,计算密集型应用,千万不要使用多线程,反而增加累赘!(GIL导致的)。

最能发挥性能的就是多进程!



 



以上是关于CPython在CPU密集型应用下的并发的主要内容,如果未能解决你的问题,请参考以下文章

Python3 源码阅读 深入了解Python GIL

Python3 并发编程3

GIL锁和线程锁

如何确定线程池的大小?

MySQL优化——什么影响了MySQL性能

Java并发编程基础