4

我已经读过用 C 实现的某些 Python 函数,我假设它们包括 file.read(),可以在它们工作时释放 GIL,然后在完成时将其恢复,这样做可以利用多个内核,如果它们'重新可用。

我正在使用多进程来并行化一些代码,目前我有三个进程,父进程,一个从文件读取数据的子进程,以及一个从第一个子进程传递给它的数据生成校验和的子进程。

现在,如果我理解这一点,似乎创建一个新进程来读取文件就像我目前正在做的那样是不必要的,我应该在主进程中调用它。问题是我是否理解这一点,我是否会在主进程或单独的进程中保持读取以获得更好的性能?

因此,鉴于我的功能是读取和管道要处理的数据:

def read(file_path, pipe_out):
    with open(file_path, 'rb') as file_:
        while True:
            block = file_.read(block_size)
            if not block:
                break
            pipe_out.send(block)
    pipe_out.close()

我认为这肯定会使用多个内核,但也会引入一些开销:

multiprocess.Process(target=read, args).start()

但现在我想知道这样做是否也会使用多个内核,减去开销:

read(*args)

任何人对哪个更快以及出于什么原因的任何见解将不胜感激!

4

2 回答 2

2

我认为这是您问题的主要部分:

问题是我是否理解这一点,并且将读取保存在主进程或单独的进程中会获得更好的性能吗?

我假设您的目标是尽可能快地读取和处理文件。在任何情况下,文件读取都受 I/O 限制,而不是 CPU 限制。处理数据的速度不能超过读取数据的速度。所以文件 I/O 显然限制了你的软件的性能。您无法通过使用并发线程/进程进行文件读取来提高读取数据速率。'低级' CPython 也没有这样做。只要您在一个进程或线程中读取文件(即使在具有 GIL 的 CPython 的情况下,线程也可以),您每次将获得尽可能多的数据,因为您可以从存储设备获得。如果您在主线程中执行文件读取也很好,只要没有其他阻塞调用实际上会减慢文件读取速度。

于 2012-08-31T11:41:24.233 回答
1

好的,正如评论所指出的,实际的问题是:

Does (C)Python create threads on its own, and if so, how can I make use of that?

简短的回答:没有。

但是,这些 C-Function 对 Python 程序员来说仍然很有趣的原因如下。默认情况下,在同一个解释器中运行的两个 python 代码片段不能并行执行,这是由于被称为Global Interpreter Lock的邪恶,也就是 GIL。每当解释器执行 Python 代码时,都会保留 GIL,这意味着上面的语句,没有两段 Python 代码可以在同一个解释器中并行运行。

尽管如此,您仍然可以在 python 中使用多线程,即当您进行大量 I/O 或大量使用外部库(如 numpy、scipy、lxml 等)时,这些都知道问题和尽可能释放 GIL(即,只要它们不需要与 python 解释器交互)。

我希望这能稍微澄清一下这个问题。

于 2012-08-31T11:28:43.213 回答