Python 当CPU利用率已经接近100%时,多线程是否有帮助?

Python 当CPU利用率已经接近100%时,多线程是否有帮助?,python,multithreading,xml-parsing,operating-system,Python,Multithreading,Xml Parsing,Operating System,我们有一个python程序,它读取大约120000个XML文件,使用ElementTree解析它们,从string.findall等中提取标记值。这需要很长时间。我们考虑使用线程来并行化程序。但是top显示这个进程的CPU消耗大约为100%。所以,我的问题是线程是否真的有用。我的直觉是,线程只有在有剩余CPU的情况下才有帮助 我的系统配置是- pavan8085@Xeek:/media/pavan8085/Projects/Pavan/CompBio$ lscpu Architecture:

我们有一个python程序,它读取大约120000个XML文件,使用ElementTree解析它们,从string.findall等中提取标记值。这需要很长时间。我们考虑使用线程来并行化程序。但是top显示这个进程的CPU消耗大约为100%。所以,我的问题是线程是否真的有用。我的直觉是,线程只有在有剩余CPU的情况下才有帮助

我的系统配置是-

pavan8085@Xeek:/media/pavan8085/Projects/Pavan/CompBio$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per core:    2
Core(s) per socket:    2
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 69
Stepping:              1
CPU MHz:               782.000
BogoMIPS:              3392.44
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              3072K
NUMA node0 CPU(s):     0-3

PS:我对Python完全陌生。因此,可能有一些特定于语言的技巧可以帮助提高速度。如果这是个问题,我很乐意提供更多的信息

肯定是因为这里最可能的瓶颈实际上是I/O而不是CPU。因此,您在这里所做的是按顺序处理每个文件,因此每次等待从磁盘读取文件时,都会遇到一个瓶颈,它会阻止所有事情的发生。如果使用多个线程,则可以同时处理多个文件,当一个文件等待I/O时,可以处理其余文件

这很好地解释了为什么I/O阻塞会导致CPU利用率高


仅仅因为它是100%,并不意味着它在这段时间内实际上在做计算工作。

肯定是因为这里最可能的瓶颈实际上是I/O,而不是CPU。因此,您在这里所做的是按顺序处理每个文件,因此每次等待从磁盘读取文件时,都会遇到一个瓶颈,它会阻止所有事情的发生。如果使用多个线程,则可以同时处理多个文件,当一个文件等待I/O时,可以处理其余文件

这很好地解释了为什么I/O阻塞会导致CPU利用率高


仅仅因为它是100%的,并不意味着它在这段时间内实际上在做计算工作。

关于Python和并发性以及Python和XML处理,有三件事是可以马上做的:

Python的多线程功能仅限于处理IO绑定的操作。有关更多说明,请查阅全局解释器锁或GIL。相反,当您有多个CPU时,要拆分并并发处理CPU绑定的工作,请使用多处理模块 当处理大型XML文件需要更快时,您不希望使用纯Python实现的ElementTree。CPython附带了一个用C编写的、名为cElementTree的相同API的实现。它将执行得更快。 虽然cElementTree速度很快,但同样实现ElementTreeAPI的世界标准lxml库速度更快。它的安装相对简单,具体取决于您的操作系统。
请看一下将工作分散到工作进程池中的一种简单方法。

关于Python和并发以及Python和XML处理,有三件事是可以马上解决的:

Python的多线程功能仅限于处理IO绑定的操作。有关更多说明,请查阅全局解释器锁或GIL。相反,当您有多个CPU时,要拆分并并发处理CPU绑定的工作,请使用多处理模块 当处理大型XML文件需要更快时,您不希望使用纯Python实现的ElementTree。CPython附带了一个用C编写的、名为cElementTree的相同API的实现。它将执行得更快。 虽然cElementTree速度很快,但同样实现ElementTreeAPI的世界标准lxml库速度更快。它的安装相对简单,具体取决于您的操作系统。
请看一看将工作分散到工作进程池中的简单方法。

假设您使用的是标准的CPython实现,则多线程不太可能在这种情况下有所帮助,因为它具有全局解释器锁,Python中的线程无法同时运行。因此,您只能使用一个CPU内核

XML解析实际上相当昂贵,而且内置的解析器不是可用的最快的解析器。已知速度更快,但如果您愿意将自己的绑定写入C或C++库,则有更快的选项。 您可能想要或提出自己的基准

您可能希望评测代码,但在使用Python评测工具时要小心,因为它们经常会被扩展模块弄糊涂,如果您正在解析XML,而您正在使用扩展模块,则很可能会被扩展模块弄糊涂


另外,根据XML的结构,解析XML文件通常不利于并行性。您可能会有很多共享状态。如果您正在处理XML并对每个元素执行一些更可能是并行化的操作,那么您可以独立地执行每个操作。我将根据您的评测显示的内容在那里花费精力。

多线程不太可能 在这种情况下,假设您使用的是标准的CPython实现,这会有所帮助,因为它有一个全局解释器锁,Python中的线程不能同时运行。因此,您只能使用一个CPU内核

XML解析实际上相当昂贵,而且内置的解析器不是可用的最快的解析器。已知速度更快,但如果您愿意将自己的绑定写入C或C++库,则有更快的选项。 您可能想要或提出自己的基准

您可能希望评测代码,但在使用Python评测工具时要小心,因为它们经常会被扩展模块弄糊涂,如果您正在解析XML,而您正在使用扩展模块,则很可能会被扩展模块弄糊涂


另外,根据XML的结构,解析XML文件通常不利于并行性。您可能会有很多共享状态。如果您正在处理XML并对每个元素执行一些更可能是并行化的操作,那么您可以独立地执行每个操作。我会根据您的评测显示的内容在那里花费精力。

以查看时间的进展情况。另外,请确保您没有使用太多内存。使用fromstring意味着一次至少要将一个文件完全读入内存,这是没有理由的。如果你读的都是这些书,你的时间可能都花在交换上了。先看看时间在哪里。另外,确保你没有使用太多的内存。使用fromstring意味着一次至少要将一个文件完全读入内存,这是没有理由的。如果您阅读了所有这些内容,那么您的时间可能都花在了交换上;在3.x中,ElementTree自动使用C加速器。此外,虽然lxml通常比stdlib的C实现快,但并不总是如此,因此值得尝试和测试。第2点仅在Python 2.x中适用;在3.x中,ElementTree自动使用C加速器。此外,虽然lxml通常比stdlib的C实现快,但并不总是如此,因此值得尝试和测试。