Родительский процесс не завершается после завершения дочернего процесса в C - PullRequest
0 голосов
/ 19 сентября 2010

У меня проблемы с процессом разминки. Я хочу разорвать дочерний процесс и заставить его зависать после объявления о его разветвлении, и ждать, пока сигнал не прекратится, после чего родительский процесс должен объявить, что он завершается, и затем завершиться.

Я могу разветвить процессы и заставить родителя дождаться, пока повисший ребенок будет убит сигналом, но, похоже, он также убивает родителя. Я пытался убить дочерний процесс, в частности, его PID, но безуспешно.

Спасибо за любую помощь!

Код:

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


void catchInt (int signum)
{
    printf("\nMy  sincerest apologies, master\n");
    /*kill(0, SIGINT);*/
    exit(0);
}

void ignoreInt (int signum)
{
    wait(NULL);
}

int main () {

    pid_t  pid;

    /* fork process */
    pid = fork();
    if (pid < 0) /* error handler */ 
    {      
        fprintf(stderr, "Fork Failed");
        exit(-1);
    }

    else if (pid == 0) /* child */    
    { 
        printf("Child reporting in\n");
        signal(SIGINT, catchInt);
        for ( ;; )
            pause();
    }

    else /* parent */
    {
        /* parent will wait for the child to complete */
        signal(SIGINT, ignoreInt);
        wait(NULL);
        printf("You're welcome\n");
        exit(0);
    }

}

Ответы [ 2 ]

3 голосов
/ 19 сентября 2010

Даже если вы исправите код, чтобы он компилировался (вы не определили tempPID), существуют проблемы:

  • Вы заставляете ребенка спать, пока не придет сигнал.
  • Вы заставляете родителя ждать, пока ребенок не умрет.

Итак, у вас есть состояние, когда ни один процесс не собирается делать больше ничего.

Возможно, вам нужен родитель, чтобы отправить сигнал ребенку:

kill(pid, SIGINT);
  • Не ясно, нужен ли родитель для установки обработчика сигнала.
  • Возможно, вы хотите, чтобы ребенок установил обработчик сигнала.
  • Возможно, вам не нужен бесконечный цикл в дочернем элементе.
  • О, и void main() неверно - int main() или int main(void) или int main(int argc, char **argv) являются утвержденными декларациями для main().
  • И будет лучше, если вы вернете значение (0) из main(). Стандарт C99 позволяет вам опускать конец main() и будет рассматривать его как возвращающий ноль, но только если функция должным образом объявлена ​​как возвращающая int.
  • Заголовок для wait() и родственников в POSIX - <sys/wait.h>.

И, поскольку я лох, вот код, который компилируется и может даже делать то, что вы хотите:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>            /* getpid() */ 
#include <stdlib.h>
#include <sys/wait.h>

void catchInt(int signum)
{
    printf("Child's PID is %d\n", (int)getpid());
    printf("My sincerest apologies, master\n");
    exit(1);
}

int main()
{
    pid_t  pid = fork();
    if (pid < 0) /* error handler */ 
    {      
        fprintf(stderr, "Fork Failed");
        exit(-1);
    }
    else if (pid == 0) /* child */    
    { 
        printf("Child reporting in\n");
        signal(SIGINT, catchInt);
        pause();
    }    
    else /* parent */
    {
        sleep(1);
        kill(pid, SIGINT);
        wait(NULL);
        printf("You're welcome\n");
    }
    return(0);
}
0 голосов
/ 19 сентября 2010

Просто выяснили, что я делаю неправильно, я должен был понять, что SIGINT отправляется каждому процессу, и поэтому родительский объект просто отправлял необработанный SIGINT, вызывая его выход.Спасибо за всю помощь (мои извинения за небрежное кодирование, я действительно не должен ждать, пока программа не будет завершена, чтобы очистить это), код был отредактирован выше и работает как задумано.

Еще раз спасибо.

...