2017-02-15 10 views
1

Я использую скрученный, чтобы вызвать локальный процесс, который может быть прерван в некоторых условиях.Как я могу получить код выхода из скрученного процесса появления, который может быть прерван неожиданным?

У меня есть обычай 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; 
} 

Выполнить пример питона напечатает

неправильное окончание: [ Экземпляр сбоя: Traceback (сбой без кадров):: Процесс закончил с вероятным условием ошибки: процесс закончился сигналом 6. ]; exitCode: None; сигнал: 6

Пример C++ будет иметь возвращаемое значение 134 при запуске в оболочке, что означает, что отправлено SIGABRT (6). (Я также протестировал отправку SIGINT, чтобы завершить и до сих пор не получить код выхода.)

Как я могу получить его в экземпляре ProcessProtocal? Или это невозможно?

+0

Итак ... вы хотите 134 вместо 6? Или что? –

+0

@ Jean-PaulCalderone Я хотел бы получить 134 или любое другое возвращаемое значение в экземпляре протокола скрученного процесса, а не 'None' в приведенном выше примере. – halfelf

ответ

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, переданном вашему ProcessProtocol, вы должны найти состояние ожидания, которое вы ищете.

+0

Спасибо! Я нашел его как атрибут класса ProcessTerminated. Это значение для платформы, и я всегда получаю '6' на моем mac, что вызывает много путаницы, пока не тестирует его на моем Linux-сервере и не получит 134 в конечном итоге. – halfelf

+0

Да, эта специфичность платформы - это то, почему обычно лучше использовать 'exitCode' и' signal'. :) –