Python多处理问题/误解

时间:2011-04-25 20:57:26

标签: python multiprocessing

我遇到了多处理问题;我在Linux 2.6.36上使用python2.7。我知道使用更高级别的模块或库会更容易,但我正在尝试使用较低级别的函数(os.fork()和os.exec *)以确保我真正理解 - 这是一种学习练习

下面是我的代码,它是一个多处理'ping'实用程序。问题是它似乎在运行时,它经常在os.wait()行上抛出一个OSError。 “没有孩子处理”

这对我来说没有意义,因为os.wait()只应在程序捕获子进程已退出且需要获取的信号时被调用。

以下代码是示例输出。

我做错了什么?

#!/usr/bin/python2.7

import os
import time
import sys
import signal

kids = []

def chldClean(SIG, FRM):
    global kids
    pid, status = os.wait()
    kids.pop(kids.index(pid))

signal.signal(signal.SIGCHLD, chldClean)

hosts = ( '10.98.232.66',
          '10.86.144.241',
          '10.86.144.242',
          '10.98.193.130',
          '10.98.198.130',
          '10.86.116.161',
          '10.86.120.161',
          '10.99.21.254',
          '10.97.98.102',
          '10.97.111.180' )


while True:
    for HOST in hosts:
        while len(kids) > 7:
            time.sleep(0.1)
        pid = os.fork()
        if pid == 0:
            os.closerange(0, 4)
            os.execl('/bin/ping', 'PING', '-c', '1', '-w', '2', HOST)
        else:
            kids.append(pid)
            print kids

带有错误的示例输出----------------------------------------

[18188]
[18188, 18189]
[18188, 18189, 18190]
[18188, 18189, 18190, 18191]
[18188, 18189, 18190, 18191, 18192]
[18188, 18189, 18190, 18191, 18192, 18193]
[18188, 18189, 18190, 18191, 18192, 18193, 18194]
[18188, 18189, 18190, 18191, 18192, 18193, 18194, 18195]
[18188, 18189, 18191, 18192, 18193, 18194, 18195, 18196]
[18188, 18191, 18192, 18193, 18194, 18195, 18196, 18197]
[18188, 18191, 18192, 18194, 18195, 18196, 18197, 18198]
[18191, 18192, 18194, 18195, 18196, 18197, 18198, 18201]
[18191, 18194, 18195, 18196, 18197, 18198, 18201, 18202]
[18191, 18195, 18196, 18197, 18198, 18201, 18202, 18203]
[18195, 18196, 18197, 18198, 18201, 18202, 18203, 18204]
[18196, 18197, 18198, 18202, 18203, 18204, 18205]
[18196, 18197, 18198, 18202, 18203, 18204, 18205, 18206]
[18197, 18198, 18202, 18203, 18204, 18205, 18206, 18207]
[18198, 18203, 18204, 18205, 18206, 18207, 18210]
[18198, 18203, 18204, 18205, 18206, 18207, 18210, 18211]
Traceback (most recent call last):
  File "./sunmon-mp", line 33, in <module>
    pid = os.fork()
  File "./sunmon-mp", line 12, in chldClean
    pid, status = os.wait()
OSError: [Errno 10] No child processes
[18203, 18204, 18205, 18206, 18207, 18210, 18211, 18212]
[18203, 18204, 18206, 18207, 18210, 18211, 18212, 18213]
[18203, 18204, 18206, 18207, 18211, 18212, 18213, 18214]
[18203, 18204, 18206, 18207, 18211, 18212, 18214, 18215]
[18203, 18204, 18206, 18207, 18212, 18214, 18215, 18217]
[18203, 18204, 18206, 18207, 18214, 18215, 18217, 18218]
[18203, 18204, 18206, 18207, 18215, 18217, 18218, 18219]
[18204, 18206, 18207, 18215, 18217, 18218, 18219, 18220]
[18204, 18206, 18207, 18217, 18218, 18219, 18220, 18221]
[18206, 18207, 18217, 18218, 18219, 18220, 18221, 18223]
[18207, 18217, 18218, 18219, 18220, 18221, 18223, 18224]
[18217, 18218, 18219, 18220, 18221, 18223, 18224, 18225]
[18217, 18219, 18220, 18221, 18223, 18224, 18225, 18226]
[18217, 18219, 18220, 18221, 18223, 18225, 18226, 18227]
[18217, 18219, 18220, 18221, 18223, 18226, 18227, 18228]
[18217, 18220, 18221, 18223, 18226, 18227, 18228, 18229]
[18217, 18220, 18221, 18223, 18227, 18228, 18229, 18230]
[18217, 18220, 18221, 18223, 18227, 18228, 18230, 18231]
[18220, 18221, 18223, 18227, 18228, 18230, 18231, 18233]
[18221, 18223, 18227, 18228, 18230, 18231, 18233, 18234]
[18223, 18227, 18228, 18230, 18231, 18233, 18234, 18235]
[18223, 18227, 18228, 18231, 18233, 18234, 18235, 18236]
[18223, 18227, 18228, 18231, 18233, 18234, 18236, 18237]
[18223, 18227, 18228, 18231, 18233, 18234, 18237, 18239]
[18227, 18228, 18231, 18233, 18234, 18237, 18239, 18240]
[18228, 18231, 18233, 18234, 18237, 18239, 18240, 18241]
[18228, 18231, 18233, 18237, 18239, 18240, 18241, 18242]
[18231, 18233, 18237, 18239, 18240, 18241, 18242, 18243]
[18231, 18233, 18239, 18240, 18241, 18242, 18243, 18244]
[18231, 18233, 18239, 18240, 18242, 18243, 18244, 18245]
[18231, 18233, 18239, 18242, 18243, 18244, 18245, 18246]
[18231, 18233, 18242, 18243, 18244, 18245, 18246, 18247]
[18233, 18242, 18243, 18244, 18245, 18246, 18247, 18248]
[18242, 18243, 18244, 18245, 18246, 18247, 18248, 18249]
[18243, 18244, 18245, 18246, 18247, 18248, 18249, 18250]
[18243, 18245, 18246, 18247, 18248, 18249, 18250, 18251]
[18243, 18245, 18247, 18248, 18249, 18250, 18251, 18252]
[18243, 18245, 18248, 18249, 18250, 18251, 18252, 18253]
[18243, 18245, 18249, 18250, 18251, 18252, 18253, 18254]
[18243, 18245, 18249, 18250, 18252, 18253, 18254, 18255]
[18245, 18249, 18250, 18252, 18253, 18254, 18255, 18258]
[18249, 18250, 18252, 18253, 18254, 18255, 18258, 18259]
[18249, 18250, 18253, 18254, 18255, 18258, 18259, 18260]
[18249, 18250, 18253, 18254, 18255, 18258, 18260, 18261]
[18249, 18250, 18253, 18254, 18255, 18260, 18261, 18262]
[18250, 18253, 18254, 18255, 18260, 18261, 18262, 18263]
[18253, 18254, 18255, 18260, 18261, 18262, 18263, 18264]
[18253, 18254, 18255, 18261, 18262, 18263, 18264, 18265]
[18253, 18254, 18255, 18261, 18262, 18264, 18265, 18266]
[18254, 18255, 18261, 18262, 18264, 18265, 18266, 18267]
[18255, 18261, 18262, 18264, 18265, 18266, 18267, 18268]
[18261, 18262, 18264, 18265, 18266, 18267, 18268, 18269]
[18261, 18262, 18265, 18266, 18267, 18268, 18269, 18270]
[18261, 18262, 18265, 18266, 18267, 18268, 18270, 18271]
[18261, 18262, 18265, 18266, 18267, 18270, 18271, 18273]
[18261, 18262, 18265, 18266, 18270, 18271, 18273, 18274]
[18261, 18262, 18265, 18266, 18271, 18273, 18274, 18275]
[18261, 18262, 18265, 18266, 18271, 18273, 18275, 18276]
[18262, 18265, 18266, 18271, 18273, 18275, 18276, 18277]
[18262, 18265, 18266, 18273, 18275, 18276, 18277, 18278]
[18265, 18266, 18273, 18276, 18277, 18278, 18280]
[18265, 18266, 18273, 18276, 18277, 18278, 18280, 18281]
Traceback (most recent call last):
  File "./sunmon-mp", line 33, in <module>
    pid = os.fork()
  File "./sunmon-mp", line 12, in chldClean
    pid, status = os.wait()
OSError: [Errno 10] No child processes
[18265, 18273, 18276, 18277, 18278, 18280, 18282]
[18265, 18276, 18277, 18278, 18280, 18281, 18282, 18283]
[18265, 18276, 18278, 18281, 18282, 18283, 18284]
[18265, 18276, 18278, 18281, 18282, 18283, 18284, 18285]
[18265, 18276, 18278, 18282, 18283, 18284, 18285, 18286]
[18265, 18276, 18278, 18283, 18284, 18286, 18289]
[18265, 18276, 18278, 18283, 18284, 18286, 18289, 18290]
Traceback (most recent call last):
  File "./sunmon-mp", line 33, in <module>
    pid = os.fork()
  File "./sunmon-mp", line 12, in chldClean
    pid, status = os.wait()
OSError: [Errno 10] No child processes
[18265, 18276, 18278, 18283, 18284, 18289, 18290, 18291]
[18276, 18278, 18283, 18284, 18289, 18290, 18291, 18292]
[18276, 18278, 18283, 18284, 18290, 18291, 18292, 18293]
[18276, 18278, 18283, 18284, 18290, 18291, 18293, 18294]
[18276, 18278, 18283, 18284, 18290, 18291, 18294, 18295]
[18278, 18283, 18284, 18290, 18291, 18294, 18295, 18297]
[18283, 18284, 18290, 18291, 18294, 18295, 18297, 18298]
[18283, 18284, 18290, 18291, 18295, 18297, 18298, 18299]

2 个答案:

答案 0 :(得分:4)

也许你受到了bug causing child processes to inherit pending signals的影响。这可以解释为什么堆栈跟踪不止一次出现。孩子正试图等待自己不存在的孩子。

同样可以同时处理多个相同类型的排队信号,因此我不建议在信号处理程序中使用wait()。

答案 1 :(得分:1)

您可能遇到this SO question中描述的相同竞争条件问题。不幸的是,我现在无法测试您的代码(Windows环境,所以没有 SIGCHLD )但似乎如果您在有问题的第12行使用os.waitpid(-1, os.WNOHANG),您将无法获得错误。但是,您仍无法保证不会遇到上述竞争条件。