Python - 创建超时(终止子进程)函数时出现的问题

发布于 2024-12-25 19:19:36 字数 2155 浏览 2 评论 0原文

我需要你在我的小程序中的支持,该程序创建一个子进程,这里是 10 次 ping,并且应该被给定的超时值 (5) 杀死。这个例子没有成功。 你能给我一个提示吗?

问候。 斯特凡

输出:

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

代码:

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':'de_DE@euro'})
    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

I need support of you in my little program, that creates a subprocess, here a 10 time ping, and should be killed by a given timeout value (5). This example does not succeed.
Can you give me a hint?

Regards.
Stefan

Output:

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':'de_DE@euro'})
    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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

下壹個目標 2025-01-01 19:19:36

您可能应该使用异常而不是警报:

class AlarmException(Exception): 
    pass 

...

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

另外,不要忘记管道可以 溢出。如果进程会为 stderr 和/或 stdout 生成太多(在某些 Linux 上大于 64k),则程序将被阻止。

You should probably use exception instead of alarm:

class AlarmException(Exception): 
    pass 

...

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

Also, do not forget that pipes can overflow. If the process will produce too much (> 64k on some Linuxes) for stderr and/or stdout, program will be blocked.

海的爱人是光 2025-01-01 19:19:36

子进程可以通过以下方式终止:

import os
os.kill(process.pid, signal.SIGKILL)

或可能:

from subprocess import Popen
Popen.kill()

或:

from subprocess import Popen
Popen.terminate()

请参阅: http:// docs.python.org/library/subprocess.html#popen-objects

a subprocess can be killed by:

import os
os.kill(process.pid, signal.SIGKILL)

or maybe:

from subprocess import Popen
Popen.kill()

or:

from subprocess import Popen
Popen.terminate()

See this: http://docs.python.org/library/subprocess.html#popen-objects

維他命╮ 2025-01-01 19:19:36

您的异常名为 Alarm,但您正在引发 alarm。 Python 区分大小写。

您可能需要将 Alarm 重命名为更具描述性的名称。像 AlarmExceptionAlarmError 这样简单的名称将使代码更清晰。

Your exception is named Alarm, but you're raising alarm. Python is case-sensitive.

You may want to rename Alarm to something more descriptive. A name as simple as AlarmException or AlarmError would make the code clearer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文