C ++ Процесс форк и sigalarm - PullRequest
       3

C ++ Процесс форк и sigalarm

2 голосов
/ 15 февраля 2012

Цель этой программы - разветвить и заставить ребенка спать, пока родительский цикл бесконечно ждет прерывания. Когда я нажимаю ^ C, он вызывает функцию void parent. Эта часть работает, однако, сообщение от kill ( pid, SIGALRM ) не работает. Я проверил, и pid является правильным идентификатором процесса для ребенка.

Я искал некоторое время, но я не нашел, что я делаю неправильно. Я использовал kill ( pid, SIGALRM ) ранее от дочернего процесса к родительскому процессу, но я не могу понять, почему это не работает ..

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

using namespace std;

int pid;

void parent ( int sig )
{
        kill ( pid, SIGALRM );
        cout << "I'm a parent " << getpid() << " My child is " << pid << endl;
}

void child ( int sig )
{
        cout << "I am " << getpid() << "my parent is " << getppid()<< endl;
        cout << "Use ctrl+backslash to actually end the program" << endl;
}
int main()
{
        pid = fork();
        if(pid == 0)
        { //Child process
                cout << "Child pid = " << getpid() << " Waiting for interrupt." << endl;
                (void) signal ( SIGALRM, child );
                pause();
        }
        else if(pid > 0)
        { //Parent
                sleep(2);
                cout << "child pid = " << pid << endl;
                struct sigaction act;
                act.sa_handler = parent;
                sigemptyset ( &act.sa_mask);
                sigaction (SIGINT, &act, 0);
                while(1)
                {
                        sleep ( 1 ); 
                }
        }
        return 0;
}

Ответы [ 2 ]

0 голосов
/ 15 февраля 2012

Вы можете сделать то же самое, что и ваше решение sigaction, просто используя signal(SIGINT, SIG_IGN);

. То, что вас изначально споткнуло (и часто запускает новых программистов, работающих с ctrl-C и сигналами),что ctrl-C посылает сигнал ВСЕЙ ГРУППЕ ПРОЦЕССА, а не одному процессу - каждый процесс в группе получит сигнал.Группа процессов, в которую посылается сигнал, является основной группой процессов терминала.

Таким образом, это дает вам множество способов иметь дело с / управления прерываниями ctrl-C.Каждый процесс может иметь свой собственный обработчик SIGINT (как вы это сделали).Или вы можете тщательно управлять своими группами процессов, помещая детей в свою собственную группу процессов (которая обычно не будет группой процессов переднего плана), чтобы они не получали сигнал в первую очередь.

Вы управляете процессомгруппы с помощью системного вызова setpgrp (2) / setpgid (2).

0 голосов
/ 15 февраля 2012

Хорошо, так что я разобрался с проблемой.
Когда я нажимал ^ C, он перехватывал прерывание в основном процессе, но убивал дочерний процесс. Когда я запустил system("ps") изнутри программы, он показал, что дочерний процесс a.out больше не работает. Чтобы исправить это, я добавил следующее к процессу ребенка:

struct sigaction act;
act.sa_handler = CHILD_PRESERVER;
sigemptyset ( &act.sa_mask);
sigaction (SIGINT, &act, 0);

Где CHILD PRESERVER была фиктивной функцией, которая ничего не делала, кроме как поддерживала ее.

Не видно, что это решение очень элегантно, поэтому, если у кого-то есть более правильный способ сделать это, пожалуйста, опубликуйте его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...