ОС: Linux
Версия Python: 3.6
Я пытаюсь расширить приложение C с помощью среды выполнения Python. Приложение C использует pthread
, а я пытался использовать multiprocessing
forkserver
в среде выполнения Python, но столкнулся с проблемой. Когда я пытаюсь завершить программу сигналом SIGINT
(нажав Ctrl+C в терминале), рабочие процессы убиваются, но основная программа зависает.
Вот игрушечная программа, которая выдает ту же проблему.
#include <Python.h>
#include <pthread.h>
void * thread_start(void *unsed)
{
PyObject *fs_mod = PyImport_AddModule("fs");
PyObject *apply_fn = PyObject_GetAttrString(fs_mod, "apply");
PyObject *job_fn = PyObject_GetAttrString(fs_mod, "job");
PyObject *job_args = Py_BuildValue("()");
PyObject_CallFunctionObjArgs(apply_fn, job_fn, job_args, NULL);
printf("finished\n");
return NULL;
}
int main(){
Py_Initialize();
PyRun_SimpleString(
"import sys; sys.path.append('...');"
"sys.argv=['a.out'];" // prepare a dummy argument to avoid error in forkserver
"import fs\n"
"if __name__ == '__main__': fs.init()");
while(1){
pthread_t thread;
pthread_create(&thread, 0, &thread_start, NULL);
printf("joing\n");
pthread_join(thread, 0);
}
}
import multiprocessing as mp
pool = None
def job():
import time
print("running..")
time.sleep(5)
def init():
global pool
mp.set_start_method('forkserver')
pool = mp.Pool(1)
def apply(*args):
global pool
return pool.apply(*args)
Я точно не знаю, как работает сигнал Linux. Я пытался поймать сигнал SIGINT
в основном процессе Python с модулем сигнала, но кажется, что основной он не получает сигнал. Как я могу заставить это приложение изящно умереть на SIGINT
, не зависая навсегда?
Прочитав ответ ViKiG, я понял, что могу сначала поймать исключение KeyboardInterrupt
(или SIGINT
) в рабочих процессах и отправить некоторое сигнальное значение в основной процесс, чтобы уведомить об исключении и закрыть приложение.
Изучив реализацию форксервера CPython, я потенциально пришел к выводу, что автор библиотеки намеренно заставил основной процесс игнорировать файл SIGINT
. Я предполагаю, что в настоящее время рекомендуется перехватывать исключение в рабочих процессах, а не в основном.