#python #signals
#python #сигналы
Вопрос:
Я пытаюсь обработать сигналы дочернего процесса subprocess.Popen(..., preexec_fn=...)
, выполняемого с.
Согласно документации, preexec_fn
выполняется в дочернем процессе, поэтому теоретически следующие две программы должны вести себя одинаково, где первая обрабатывает сигнал внутри встроенного кода c, а вторая обрабатывает сигнал извне с помощью функции python.
Однако, изучив код выхода, равный 0 или нет, я обнаружил, что на самом деле работает только обработка внутри кода C. У кого-нибудь есть идея, почему обработка сигналов в python не работает?
Спасибо!
обработка изнутри, выход с 0:
from tempfile import TemporaryDirectory
import subprocess
import signal
import os
c_code = """
#include <csignal>
#include <cstdlib>
#include <iostream>
int main() {
std::signal(SIGFPE, [](int){std::quick_exit(0);}); // handling the signal here
std::cout <<3/0 <<std::endl;
}
"""
def handle_sigfpe():
# signal.signal(signal.SIGFPE, lambda: os.exit(0)) # not handling here
pass
def main():
print(f'main pid: {os.getpid()}', flush=True)
with TemporaryDirectory() as d:
code_path = f'{d}/a.cpp'
bin_path = f'{d}/a'
with open(code_path, 'w') as f:
print(c_code, file=f)
assert(subprocess.run(['g ', '-o', bin_path, code_path]).returncode == 0)
p = subprocess.Popen([bin_path], preexec_fn=handle_sigfpe)
p.wait()
print(f'return code: {p.returncode}', flush=True)
main()
обработка извне, выход с -8 (SIGFPE):
from tempfile import TemporaryDirectory
import subprocess
import signal
import os
c_code = """
#include <csignal>
#include <cstdlib>
#include <iostream>
int main() {
// std::signal(SIGFPE, [](int){std::quick_exit(0);}); // not handling the signal here
std::cout <<3/0 <<std::endl;
}
"""
def handle_sigfpe():
signal.signal(signal.SIGFPE, lambda: os.exit(0)) # but here
pass
def main():
print(f'main pid: {os.getpid()}', flush=True)
with TemporaryDirectory() as d:
code_path = f'{d}/a.cpp'
bin_path = f'{d}/a'
with open(code_path, 'w') as f:
print(c_code, file=f)
assert(subprocess.run(['g ', '-o', bin_path, code_path]).returncode == 0)
p = subprocess.Popen([bin_path], preexec_fn=handle_sigfpe)
p.wait()
print(f'return code: {p.returncode}', flush=True)
main()