【问题标题】:why process doesn't join and doesn't run?为什么进程不加入并且不运行?
【发布时间】:2013-03-20 07:09:26
【问题描述】:

我有一个简单的问题要解决(或多或少)
如果我观看 python 多处理教程,我会发现一个进程或多或少应该像这样启动:

from multiprocessing import *

def u(m):
    print(m)
    return

A=Process(target=u,args=(0,))
A.start()
A.join()

它应该打印一个 0 但没有打印任何内容。相反,它永远挂在A.join()

如果我手动启动你这样做的功能

A.run()

它实际上在 shell 上打印 0,但它不能同时工作
例如以下代码的输出:

from multiprocessing import *
from time import sleep

def u(m):
    sleep(1)
    print(m)
    return

A=Process(target=u,args=(1,))
A.start()
print(0)

应该是
0
1

其实是
0

如果我在最后一行之前添加

A.run()

然后输出变成
1
0

这让我感到困惑......

如果我尝试加入该过程,它会永远等待。

但是,如果它可以帮助给我一个答案
我的操作系统是 Mac os x 10.6.8
使用的 python 版本是 3.1 和 3.3
我的电脑有 1 个英特尔酷睿 i3 处理器

--更新--
我注意到这种奇怪的行为只有在从 IDLE 启动程序时才会出现,如果我从终端运行程序,一切都按预期工作,所以这个问题必须与一些 IDLE 错误有关。
但是从终端运行程序更奇怪:使用 range(100000000) 之类的东西会激活我所有计算机的内存,直到程序结束;如果我记得很清楚,这不应该发生在 python 3 中,只发生在较旧的 python 版本中。 我希望这些新信息能帮助您给出答案

--更新 2--
即使我不从我的进程执行输出,也会出现错误,因为设置了这个:

def u():
    return

作为进程的目标然后启动它,如果我尝试加入进程,空闲等待永远

【问题讨论】:

  • 我不能告诉你为什么,这就是为什么我没有发布这个作为答案,但是创建进程的所有示例在目标中都没有return 语句(这与Pool 目标)。您是否尝试过从 u 中删除 return 语句?
  • @sr2222 不。return 等同于return None。模控制流(在 OP 的示例中不是问题),根本没有 return 与返回 None 相同。
  • 你的两个例子在我安装的所有 python 版本上都给了我在 linux 上的预期结果。
  • @delnan,是的,我知道对于正常情况,但我不确定是否在 C 扩展的内部 _multiprocessselectfcntl 库中,有一些细微的差别,它被暴露在这里。
  • 你认为赏金可以帮助我找到答案吗?

标签: python macos python-3.x parallel-processing multiprocessing


【解决方案1】:

您是否尝试过无缓冲输出?尝试导入 sys 模块并更改打印语句:

print >> sys.stderr, m

这对行为有何影响?我和其他怀疑 IDLE 与 stdio 混在一起的人在一起。 . .

【讨论】:

    【解决方案2】:

    正如herehere 所建议的那样,问题在于IDLE 以一些奇怪的方式覆盖了sys.stdinsys.stdout,它们不会干净地传播到您从中产生的进程(它们不是真正的文件句柄)。

    第一个链接还表明它不太可能很快得到修复(他们说,“可能是一个'无法修复'的问题”)。

    所以不幸的是,我可以建议的唯一解决方案是不要对这个脚本使用 IDLE...

    【讨论】:

      【解决方案3】:

      鉴于它只发生在 IDLE 中,我怀疑问题与两个进程使用的标准输出有关。可能是一些类似文件的对象在两个不同的进程中使用是不安全的。

      如果您没有子进程写入标准输出,我怀疑它会完成并正确加入。例如,您可以改为将其写入文件。或者你可以在父母和孩子之间建立一个管道。

      【讨论】:

      • 即使我给我的子进程一个任务,比如做一些算术,不使用输入或输出,或者写入文件,任务管理器告诉我只有一个 CPU 内核在使用跨度>
      • 这不是一个明智的测试。除非该核心的利用率达到或接近 100%,否则没有理由仅仅因为存在另一个进程而使用另一个核心。问题是:子进程是否成功完成,父进程的加入请求是否成功?
      【解决方案4】:

      您是否尝试将A.join() 添加到您的程序中?我猜你的主进程在子进程打印之前退出,这导致输出被隐藏。如果你告诉主进程等待子进程(A.join()),我敢打赌你会看到你期望的输出。

      【讨论】:

      • 不,如果我尝试 A.join(),python 解释器将永远等待,并且子进程不会像我在问题中所说的那样运行
      • 对不起,我读了代码并没有意识到这就是你在标题中的意思。我已经编辑了问题本身以包括对 A.join 的调用。我会再考虑一下。
      猜你喜欢
      • 2021-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-05
      • 1970-01-01
      • 1970-01-01
      • 2016-08-31
      • 1970-01-01
      相关资源
      最近更新 更多