2012-01-06 21 views
0

私は自分の小さなプログラムでサブプロセスを作成します。ここでは10回のpingを行い、タイムアウト値(5)で殺す必要があります。この例は成功しません。 私にヒントを教えてもらえますか?Python - タイムアウト(killサブプロセス)関数を作成する際の問題

よろしくお願いいたします。 ステファン

出力:

Traceback (most recent call last): 
File "./nwcheck.py.work", line 146, in <module> 
MyCheck().check().exit() 
File "./nwcheck.py.work", line 80, in check 
output = process.communicate() 
File "/usr/lib/python2.6/subprocess.py", line 701, in communicate 
return self._communicate(input) 
File "/usr/lib/python2.6/subprocess.py", line 1199, in _communicate 
rlist, wlist, xlist = select.select(read_set, write_set, []) 
File "./nwcheck.py.work", line 29, in alarm_handler 
raise alarm 
TypeError: exceptions must be old-style classes or derived from BaseException, not builtin_function_or_method 

CODE:

def check(self): 

    class Alarm(Exception): 
     pass 

    def alarm_handler(signum, frame): 
     raise alarm 

    def get_process_children(pid): 
     p = Popen('ps --no-headers -o pid --ppid %d' % pid, shell = True, 
        stdout = PIPE, stderr = PIPE) 
     stdout, stderr = p.communicate() 
     return [int(p) for p in stdout.split()] 
    timeout = 5 
    args2 = [ 
      'ping', 
      'localhost', 
      '-c 10', 
      ] 
    process = subprocess.Popen(args2, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env={'LANG':'[email protected]'}) 
    processpid = process.pid 
    print processpid 
    if timeout != -1: 
     signal(SIGALRM, alarm_handler) 
     alarm(timeout) 
     print 'in timeout abfrage' 
    try: 
     ## catch stdout and stderr 
     output = process.communicate() 
     if timeout != -1: 
      alarm(0) 
      print 'in timeout abfrage 2' 
    except Alarm: 
     pids = [process.pid] 
     print pids 
     if kill_tree: 
      pids.extend(get_process_children(process.pid)) 
     for pid in pids: 
     # process might have died before getting to this line 
     # so wrap to avoid OSError: no such process 
      try: 
       kill(pid, SIGKILL) 
      except OSError: 
       pass 
     return -9, '', '' 

    # Return a response 
    return output 

答えて

2

class AlarmException(Exception): 
    pass 

... 

    def alarm_handler(signum, frame): 
     raise AlarmException() 

また、パイプがoverflowできることを忘れないでください。 stderrやstdoutに対してプロセスが多すぎる(いくつかのLinuxでは64k以上)ことがあると、プログラムはブロックされます。

+0

はい、あなたは正しいです。今はうまくいきません。 – StefanS

0

あなたの例外がAlarmという名前が付けられていますが、alarmを上げています。 Pythonでは大文字と小文字が区別されます。

Alarmの名前をもっとわかりやすい名前に変更することができます。 AlarmExceptionまたはAlarmErrorのような単純な名前は、コードを明確にします。

おそらく代わりに、アラームの例外を使用する必要があります
+0

ありがとう、それがポイントです。 – StefanS

関連する問題