Объяснение об использовании SIGKILL - PullRequest
0 голосов
/ 02 декабря 2018

Спасибо, что прочитали это, я очень ценю!У меня есть эта часть кода:

for(i=0;i<n;i++)
    {
        printf("dopo %d sec ricevuto kill\n",20-sleep(20));
        kill( pidFiglio[i],SIGKILL);
    }

    for (i=0 ; i<n ; i++)
    {
        //attesa della terminazione di un processo figlio
        pidDaWait = wait( & status );
        //(...)

, но я не могу понять, почему процесс отца может ждать своих сыновей, после того как он их убил!Функция kill возвращает 0, поэтому она работает, но отец может ждать «своих сыновей» после.Я знаю, что это глупый ответ, но я абсолютно новичок в мультипрограммировании.

#include <stdio.h>
#include <stdlib.h>     //per la exit()
#include <unistd.h> //per la fork()
#include <sys/types.h> //per la wait()
#include <sys/wait.h>   //per la wait()
#include <signal.h>        //per la signal()

int contSigusr1;

void trapSIGUSR1(int nsignal);

int main( int argc , char* argv[] )
{
    int i;
    int n;
    pid_t pidFiglio[10];
    pid_t pidDaWait;
    int status;     

    contSigusr1=0;
    signal ( SIGUSR1, trapSIGUSR1 );

    printf("argc = %d\n", argc);

    if ( argc < 3 )
    {
        printf("Sintassi errata!\n");
        printf("il programma termina con errore\n");
        exit(1);
    }
    n = atoi( argv[1] );


    for (i=0; i<n; i++)
    {
        pidFiglio[i] = fork();
        if ( pidFiglio[i] == 0 )
        {
            printf("Figlio - getpid = %d\n", getpid());
            printf("Figlio - getppid = %d\n", getppid());


            printf("(%d)%s\n",getpid(),argv[2+i]);

            sleep(i*5);

            kill( getppid() , SIGUSR1);

            sleep(i+1*5);

            printf("Figlio - termina correttamente\n");    

            exit(0);
        } 
    }
    printf("getpid = %d\n", getpid());
    printf("getppid = %d\n",getppid());
    for(i=0;i<n;i++)
    {
        printf("dopo %d sec ricevuto kill\n",20-sleep(20));
        kill( pidFiglio[i],SIGKILL);
    }

    for (i=0 ; i<n ; i++)
    {
        pidDaWait = wait( & status );

        printf("status = %d\n", status);
        printf("status di (%d) con WEXITSTATUS = %d\n",
                   pidDaWait,
                   WEXITSTATUS( status));
        if ( WIFSIGNALED (status) )
            printf("il processo figlio (%d) e` terminato tramite un segnale\n",pidDaWait);
        else
            printf("il processo figlio (%d) e` terminato normalmente\n",pidDaWait);
    }
    printf("il padre termina dopo la terminazione del processo figlio con pid = %d\n",pidDaWait );
    exit(0);
}

void trapSIGUSR1(int nsignal) 
{
    contSigusr1= contSigusr1 +1;
    printf("riceived %d SIGUSR1 = %d\n",nsignal,contSigusr1);
}

Просто не обращайте внимания на итальянские слова: D Заранее спасибо, хорошего дня!

1 Ответ

0 голосов
/ 02 декабря 2018

Чайлдс все еще существует, но теперь зомби .

Дочерние объекты могут прекратить выполнение, но task_struct все еще существует в ядре.task_struct в ядре содержит информацию о состоянии возврата от ребенка (и некоторую другую информацию).Зомби task_struct существует только для того, чтобы родительский процесс мог получить дочерний статус возврата (через wait(&status) + WEXITSTATUS(status)) и другую информацию о дочернем элементе, чтобы родительский код мог быть согласованным.

ОтправкаSIGKILL для детей или удаление всех детей с помощью вызова exit() (как в википедии) не имеет значения - в результате дочерний процесс становится зомби.После того, как родительский вызов wait и что wait обслуживает этого потомка, он task_struct из ядра get free d и информация о статусе get возвращается родителю, поэтому он может с этим справиться.

...