【问题标题】:[multiprocessing python]: no output[多处理python]:没有输出
【发布时间】:2021-05-13 01:46:04
【问题描述】:

有人可以解释一下为什么当我尝试执行以下示例时,我没有结果。 我也尝试将输出重定向到文件中,但没有成功。

from multiprocessing import Process
def proc(i):
    print(f'I am Process {i}')
if __name__ ==  '__main__':
    for i in range(10):
        Process(target=proc, args=(i,)).start()

通常,我有输出:

I am Process 6
I am Process 2
I am Process 0
I am Process 3
I am Process 7
I am Process 4
I am Process 8
I am Process 1
I am Process 5
I am Process 9

但就我而言,我没有结果。

【问题讨论】:

  • 您已编辑问题以更正错误,但未表明您已这样做。人们会过来看看这个,现在想知道为什么你没有从正确的程序中得到任何输出。
  • 我没有更正错误。 (只是我在stackoverflow中编写代码时犯了一个错误,并且在编写if`__name__`的内部并且我写了_name_and这不是我的问题。如果是这种情况,我应该得到一个NameError:name'name ' 未定义)但我的问题是:尽管代码是正确的,但我总是遇到同样的问题,即多处理在我的情况下不起作用并且我没有输出。感谢您的不理解
  • 很高兴你澄清了这一点。根据您的错字已经有答案。请参阅下面的答案。

标签: python multiprocessing python-multiprocessing


【解决方案1】:

您需要强制刷新,否则只有在缓冲区已满时才能看到输出:

def proc(i):
    print(f'I am Process {i}')
    sys.stdout.flush()

PS:您在检查__name__ 时也会出现拼写错误。应该是if __name__ == '__main__':

【讨论】:

  • 我会像你说的那样尝试强制刷新,因为即使我删除 if name 并尝试 jupyter 中的代码也没有输出
  • 我试了一下也是同样的问题
  • @Ishraq 你如何执行你的python程序?
  • @Ishraq 我明白了 - 请在此处参考此答案:stackoverflow.com/questions/23641475/…
  • 非常感谢您提到的文章。此回复对我有帮助:stackoverflow.com/a/59569742/12187211
【解决方案2】:

这可能是if _name_ == '__main__': 中的拼写错误,缺少下划线。

跑步:

from multiprocessing import Process

def proc(i):
    print(f'I am Process {i}')

if __name__ == '__main__':
    for i in range(10):
        Process(target=proc, args=(i,)).start()

在我的机器上返回正确的输出

【讨论】:

  • 抱歉不是这个问题,这只是我在这里写代码时的一个错误。尽管我写对了,但我没有结果
  • 尝试将 i 设置在 range(150) 中并在任务管理器中检查您的 cpu 活动,以检查进程是否正在实际创建中。
  • 是的,当我在任务管理器中检查我的 cpu 活动时,我观察到进程正在创建,但我在 spyder 或 jupyter 中没有得到任何结果
【解决方案3】:

如果您必须在 Notebook 下运行(并已根据需要将工作函数移至外部模块)并且希望在 Notebook 中查看打印输出,则需要安排打印由主(启动)完成过程。这意味着启动的进程需要将要打印的字符串返回给启动进程。有几种方法可以做到这一点。在这里,我使用了一个带有回调函数的多处理池,以便一旦结果准备好,主进程就会被回调并返回结果:

from multiprocessing import Pool
from workers import proc

def on_completion(result):
    print(result)

if __name__ ==  '__main__':
    pool = Pool(10)
    results = [pool.apply_async(proc, args=(i,), callback=on_completion) for i in range(10)]
    pool.close()
    pool.join() # wait for worker processes to exit

第二种更简单的方法:

from multiprocessing import Pool
from workers import proc


if __name__ ==  '__main__':
    pool = Pool(10)
    results = pool.imap_unordered(proc, range(10))
    # print the results as they become available:
    for result in results:
        print(result)

使用 ProcessPoolExecutor:

from concurrent.futures import ProcessPoolExecutor, as_completed
from workers import proc


if __name__ ==  '__main__':
    with ProcessPoolExecutor(max_workers=10) as executor:
        futures = [executor.submit(proc, i) for i in range(10)]
        for f in as_completed(futures):
            print(f.result())

【讨论】:

  • 感谢您的回复。是的,单元格下面什么都没有,但是请告诉我如何访问笔记本控制台
  • 为什么一定要在Notebook下运行这个?你不能从 Windows/Linux 命令提示符运行这个(或你的原始代码)吗?但是如果你必须在 Notebook 下运行,我已经更新了我的答案。
  • 好的,谢谢,这对我有用
  • 老实说,我不知道笔记本为什么会这样。我的猜测是它捕获写入标准输出的输出,然后将其写入单元格下。但它仅针对单元中运行的进程执行此操作,而不针对它创建的任何子进程。您应该阅读多处理池。 Python 附带了两个用于执行此操作的类,模块multiprocessing 中的类Pool 和模块concurrent.futures 中的类ProcessPoolExecutor。我将使用ProcessPoolExecutor 添加一个示例。
猜你喜欢
  • 2022-01-03
  • 1970-01-01
  • 2018-06-13
  • 1970-01-01
  • 2019-01-16
  • 2013-03-30
  • 1970-01-01
  • 1970-01-01
  • 2016-10-01
相关资源
最近更新 更多