Родитель убивает n детей, используя сигналы после того, как родитель создает их - PullRequest
0 голосов
/ 24 апреля 2020

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

Когда родитель убивает дочернего элемента, родительский нужно подождать 2 секунды, прежде чем убить следующего. Наконец, когда родитель убил всех дочерних элементов, родитель должен также завершить sh.

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

Вот код:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>

void handle_sigint(int sig) { 
    signal(sig,handle_sigint);
    exit(0);
} 

int main(int argc, char *argv[]) {
    char *ptr=argv[1];
    int n=atoi(ptr);//number of processes to be created
    pid_t p[n];

    for(int i = 0; i < n; i++) {  
        signal(SIGINT, handle_sigint);    
        if ((p[i] = fork()) == 0) {
            while(1) 
                printf("%d %d\n",getpid(),i);                   
        } 
        sleep(2);                                
    }

    for (int i = 0; i < n; i++) {
        kill(p[i],SIGINT);
        sleep(2);
    }

    for (int i = 0; i < n; i++) {
        wait(NULL);
    }

    return 0;
}

1 Ответ

0 голосов
/ 24 апреля 2020

Во-первых, вам не нужен обработчик сигналов, потому что есть много сигналов, действие которых по умолчанию заключается в прекращении процесса приема. SIGINT, который вы уже используете, на самом деле является одним из них, но SIGTERM будет более подходящим выбором для этой цели. Я бы упростил избавление от обработчика и его регистрации, и я бы попросил родителя отправить SIGTERM вместо SIGINT.

Если вы все же сохраните обработчик сигнала, тогда вам следует использовать sigaction(), а не signal(), чтобы зарегистрировать его, и вы должны пропустить перерегистрацию из реализации обработчика, так как правильное использование sigaction() делает это ненужным. Кроме того, обработчикам сигналов разрешается вызывать только asyn c -signal-safe функции , и exit() не является одним из них. Вы могли бы использовать _exit() или _Exit() вместо этого, но, опять же, было бы проще просто отбросить обработчик.

Все это несмотря на это, однако, я склонен подозревать, что причина в исходном коде сбой был неверной подписью обработчика сигнала, которую вы исправили в своем редактировании. Для обработчика все еще неправильно вызывать exit(), но на практике вполне вероятно, что проявление результирующего неопределенного поведения включает завершение программы.

...