我使用twisted来生成本地进程,可能会在某些情况下终止。
我有一个反应堆的自定义twisted.internet.protocol.ProcessProtocol
类。如果本地进程突然终止,我无法在processEnded
中获得返回值。 exitCode
设置为None
。
mcv示例如下:
from twisted.internet import error,protocol,reactor
class MyPP(protocol.ProcessProtocol):
def processEnded(self, reason):
if reason.check(error.ProcessTerminated):
err_info = "wrong termination: %s; exitCode: %s; signal: %s" % \
(reason, reason.value.exitCode, reason.value.signal)
print(err_info)
else:
print("processEnded, status %d" % (reason.value.exitCode,))
print("quitting")
reactor.stop()
pp = MyPP()
reactor.spawnProcess(pp, "throw_exception", ["throw_exception"], {})
reactor.run()
throw_exception
可执行文件可以从以下编译:
#include <iostream>
int main() {
throw std::runtime_error("some exception");
return 0;
}
执行python示例将打印
错误终止:[失败实例:回溯(失败,没有 frames)::一个过程 以可能的错误条件结束:过程由信号6结束。 ]。 exitCode:无;信号:6
如果在shell中运行,C ++示例的返回值为134,这意味着发送了SIGABRT
(6)。 (我还测试了发送SIGINT
以终止并仍然没有退出代码。)
如何在ProcessProtocal
实例中获取它?或者这是不可能的?
答案 0 :(得分:1)
在您的示例中,134是“等待状态”(或在手册页中,“wstatus”)。它编码了一些有关正在进行wait()
过程的运行状态转换的信息。
可能的转变是:
exit(2)
)SIGSTOP
)SIGCONT
) POSIX提供用于从等待状态中提取详细信息的宏:WIFEXITED
,WIFSIGNALED
,WTERMSIG
,WEXITSTATUS
等。
Python通过os
模块公开这些内容:os.WIFEXITED
等等。
os.WIFEXITED(134)
评估为False
。 os.WIFSIGNALED(134)
评估为true,os.WTERMSIG(134)
评估为6
。
ProcessDone
和ProcessTerminated
使用这些宏来提取信息并以更有用的形式呈现 - exitCode
和signal
属性。
虽然POSIX没有提供一种方法来使用其他方式。没有用于构建“等待状态”的标准API,例如,“该过程被信号6杀死”。
幸运的是,部分因为没有办法倒退,Twisted会将异常的原始等待状态保留为status
属性。如果您检查传递给Failure
的{{1}}中包含的异常上的该属性,您应该找到您正在寻找的等待状态。