9

如果我观看 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()

它实际上在外壳上打印 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

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

4

4 回答 4

7

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

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

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

于 2013-04-08T05:39:16.083 回答
0

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

print >> sys.stderr, m

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

于 2013-04-09T03:39:35.717 回答
0

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

于 2013-03-29T17:31:44.580 回答
0

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

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

于 2013-04-08T03:36:16.353 回答