【问题标题】:Explanation about a use of SIGKILLSIGKILL 的使用说明
【发布时间】:2018-12-02 11:38:14
【问题描述】:

感谢您阅读本文,非常感谢! 我有这部分代码:

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 先感谢您, 祝你有美好的一天!

【问题讨论】:

  • wait 用于清理子进程的资源,父进程可能仍需要诊断子进程的终止原因,因此 linux 将其保留为“僵尸”进程。父进程有责任使用wait清理其子进程的资源。
  • 所以,当我像信号一样使用 SIGKILL 时,我会终止进程但我不会清理资源,因此父亲“看到”了儿子,即使它已终止(或者更好的是,父看到资源以便在等待中清理它们)。我说的对吗?

标签: c linux fork kill sigkill


【解决方案1】:

孩子仍然存在,但现在是zombies

子进程可以终止他们的执行,但task_struct 仍然存在于内核中。内核中的task_struct 保存来自子进程的返回状态信息(以及其他一些信息)。僵尸task_struct的存在只是为了让父进程可以得到子进程的返回状态(通过wait(&amp;status)+WEXITSTATUS(status))和其他关于子进程的信息,这样父进程的代码才能保持一致。

向子进程发送SIGKILL 或使用exit() 调用终止所有子进程(就像在维基百科中一样)并不重要——结果是子进程变成了僵尸进程。父调用wait后,wait为子服务,从内核get的freed得到task_struct,状态信息get返回给父处理。

【讨论】:

    猜你喜欢
    • 2017-05-28
    • 2019-12-10
    • 1970-01-01
    • 1970-01-01
    • 2017-02-16
    • 2018-03-06
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多