Родительский процесс не завершается после завершения дочернего процесса в C

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

Я могу получить ответвление процессов и заставить родителя ждать, пока висящий дочерний элемент не будет убит сигналом, но, похоже, он также убивает родителя. Я попытался убить дочерний процесс специально по его 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);
    }

}

person JKomusin    schedule 18.09.2010    source источник
comment
Код, который вы показываете, не компилируется - вы не определили tempPID. Вам не нужно <unistd.h> дважды, а в наши дни не нужно <sys/types.h> (хотя в некоторых более ранних версиях POSIX это было необходимо).   -  person Jonathan Leffler    schedule 19.09.2010
comment
Это не компилируется, и это не имеет особого смысла, даже если это так. tempPID полностью не объявлен и читается в обработчике сигналов, который используется только в родительском процессе, несмотря на то, что он установлен только в дочернем процессе. По крайней мере, исправьте это, и мы увидим, где мы сможем вас оттуда достать.   -  person Tim Yates    schedule 19.09.2010


Ответы (2)


Даже если вы исправите код, чтобы он компилировался (вы не определили 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);
}
person Jonathan Leffler    schedule 18.09.2010
comment
Я привел в порядок код, tempPID был остатком попытки различных способов убить ребенка. Причина, по которой оба процесса зацикливаются бесконечно, заключается в том, что они ждут отправки сигнала SIGINT нажатием CTRL + C, я должен был пояснить. Также Джонатан, код не будет компилироваться без sys / types.h для передачи прототипа для pid_t. - person JKomusin; 19.09.2010
comment
@ Джош: в какой среде вы работаете, где еще требуется явное <sys/types.h>? Я давно не встречал такой машины - лет пять как минимум. Но, как я отмечал в первоначальном комментарии, было время, когда стандарт POSIX или Стандарт UNIX Specification 1997 требовал этого. - person Jonathan Leffler; 19.09.2010

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

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

person JKomusin    schedule 18.09.2010