为什么在Python多进程池(multiprocessing pool)中使用`print`无法正常工作?

11

我正在尝试使用 multiprocessing 模块来处理一个大的 csv 文件。我正在使用 Python 2.7,并按照这里的示例进行操作。

我运行了未修改的代码(为方便起见,以下是复制的代码),发现 worker 函数内的 print 语句不起作用。无法打印输出使得难以理解流程并进行调试。

有人能否解释一下为什么这里不能使用 print?难道 pool.map 不执行 print 命令吗?我在网上搜索了一番,但没有找到任何相关的文档资料。

import multiprocessing as mp
import itertools
import time
import csv

def worker(chunk):
    # `chunk` will be a list of CSV rows all with the same name column
    # replace this with your real computation
    print(chunk)     # <----- nothing prints
    print 'working'  # <----- nothing prints
    return len(chunk)  

def keyfunc(row):
    # `row` is one row of the CSV file.
    # replace this with the name column.
    return row[0]

def main():
    pool = mp.Pool()
    largefile = 'test.dat'
    num_chunks = 10
    results = []
    with open(largefile) as f:
        reader = csv.reader(f)
        chunks = itertools.groupby(reader, keyfunc)
        while True:
            # make a list of num_chunks chunks
            groups = [list(chunk) for key, chunk in
                      itertools.islice(chunks, num_chunks)]
            if groups:
                result = pool.map(worker, groups)
                results.extend(result)
            else:
                break
    pool.close()
    pool.join()
    print(results)

if __name__ == '__main__':
    main()

2
你是如何运行你的程序的?一些集成开发环境可能没有以允许工作进程向其写入的方式设置虚拟终端。然而,如果你尝试从命令行运行你的程序,我会期望打印输出能够正常工作。 - Blckknght
我认为@Blckknght是正确的。像那样打印应该没问题。如果我采用你的确切代码,传递一个硬编码的列表而不是读取csv文件,并通过CLI运行它,它会像应该打印的那样。 - dano
@Blckknght - 感谢您的回复。我正在通过IDLE运行。 - Roberto
@Josh Caswell - 谢谢。sys.stdout.flush()的解决方案在worker中不起作用(会出现“坏文件描述符”错误)。但我会继续尝试这个思路。 - Roberto
1个回答

16

这是一个与IDLE相关的问题,您正在使用它来运行代码。IDLE对于处理在其中运行程序的输出,进行了基本模拟终端的仿真。但是,它无法处理子进程,所以虽然它们可以在后台运行得很好,但您永远看不到它们的输出。

最简单的解决方法是从命令行中运行您的代码。

另一种选择可能是使用更复杂的集成开发环境。在Python维基上列出了一堆工具,但我不确定哪些工具在多处理输出方面具有更好的终端仿真功能。


谢谢,当我在家里(用Eclipse)运行时,一切正常。我的工作环境是非常简单的,所以我使用IDLE而不是IDE。对于这个特定的项目,我可能需要重新考虑一下。 - Roberto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接