我用Python编写了一个工作程序,基本上解析了一批二进制文件,将数据提取到数据结构中。每个文件大约需要一秒钟来解析,这意味着数千个文件的小时数。我已经成功实现了具有可调整线程数的批处理解析方法的线程版本。我在具有不同线程数的100个文件上测试了该方法,每次运行计时。以下是结果(0个线程指的是我原来的预线程代码,1个线程到新版本运行时产生的单个线程)。
0 threads: 83.842 seconds
1 threads: 78.777 seconds
2 threads: 105.032 seconds
3 threads: 109.965 seconds
4 threads: 108.956 seconds
5 threads: 109.646 seconds
6 threads: 109.520 seconds
7 threads: 110.457 seconds
8 threads: 111.658 seconds
虽然生成一个线程会比主线程执行所有工作带来小的性能提升,但实际上的线程数会增加性能。我本来希望看到性能提升,至少最多四个线程(每个机器核心一个)。我知道线程有相关的开销,但我认为这对于一位数的线程来说并不重要。
我听说过“全局解释器锁定”,但是当我移动到四个线程时,我确实看到了相应的内核数量 - 两个线程两个核心在解析期间显示活动,依此类推。 / p>
我还测试了一些不同版本的解析代码,看看我的程序是否是IO绑定的。它似乎不是;只读文件需要相对较小的时间;处理文件几乎就是全部。如果我不执行IO并处理已读取的文件版本,我添加第二个线程会损害性能,第三个线程会略微改进它。我只是想知道为什么我不能利用我的计算机的多核来加快速度。请发布我可以澄清的任何问题或方法。
答案 0 :(得分:39)
令人遗憾的是CPython中的情况如何,主要是由于Global Interpreter Lock(GIL)。 CPU绑定的Python代码不能跨线程扩展(另一方面,I / O绑定代码可能在某种程度上扩展)。
David Beazley提供了一个信息量很大的presentation,他讨论了围绕GIL的一些问题。视频可以找到here(感谢@Ikke!)
我的建议是使用multiprocessing
模块而不是多线程。
答案 1 :(得分:9)
线程库实际上并不同时使用多个内核进行计算。您应该使用multiprocessing库代替计算线程。