обработка сигналов в preexec_fn подпроцесса.Popen не работает

#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()