LINUX.ORG.RU

удаление дочернего процесса ?


0

0

Здраствуйте. Не подскажите, можно дочерний процесс сделать дочерним на 
иерархию выше.

//parent-0
if (fork() == 0)
  {   //child-1 (parent-1)
      if (fork() == 0)
       {   //child-2
           ....  
       }
    ....
  }

Можно ли  процесс 'child-2' сделать дочерним для 'parent-0' непосредственно ?
Очень хочется вешать обработчик сигнала 'SIGCHLD' для процесса 'child-2'
в 'parent-0'.
Еслт не сложно подскажите пожалуйста есть ли такой стандартный механизм
 или функция переназначения или можно как нибудь это сделать ? 
Или есть какая хитрость ? 
anonymous

Ответ на: комментарий от anonymous

А как становятся процессы сыновьями процесса init, когда родительский процесс
умирает ?

anonymous
()
Ответ на: комментарий от anonymous

изменить parent у процесса нельзя.

> как становятся процессы сыновьями процесса init,
> когда родительский процесс умирает

это происходит автоматически, в том смысле, что это
делает ядро, см kernel/exit.c:forget_original_parent()

idle ★★★★★
()
Ответ на: комментарий от anonymous

> А нельзя с помощью ядра изменить parent ?

не очень понял вопрос. еще раз, изменить parent
нельзя. разумеется, можно модифицировать ядро так,
чтобы это стало возможно, технически это не очень
сложно реализовать. но я бы не советовал.

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

в 2.6 вы можете воспользоваться CLONE_CHILD_CLEARTID
или sys_set_tid_address() и у вас будет futex, который
получит wake при завершении процесса.

можно и стандартными средствами, что-то вроде:

int fd[2];

pipe(fd));
fcntl(fd[0], F_SETOWN, getpid());
fcntl(fd[0], F_SETSIG, SIGBUS); // или какой вам нравится
ioctl(fd[0], FIOASYNC, fd);

if (fork()) {
        close(fd[1]);
        for (;;);               // ждем сигнала
}
else if (fork())
        close(fd[1]);
else {
        // что-то делаем
        exit(0);                // парент получит SIGBUS
}

idle ★★★★★
()
Ответ на: комментарий от idle

Да вопрос был задан в общем наверное не правильно.
Мне не обязательно ненять parent, не нужно да-же.
мне нужно обработать сигнал SIGCHLD от косвенного потомка.
Не только его поймать, чтоб обработчик вызвался, но еще и 
чтоб системный вызов wait() или waitpid() смогли сработать. 
Как я понял из приведенного примера это возможно, но не очень понятно.
Я пока не работал с fcntl() и ioctl().
А у Стивенса описано работа с этими функциями, не знаете случайно ?
В любом случае спасибо знаю, что еще покопать и в какую сторону. 

anonymous
()
Ответ на: комментарий от anonymous

> Не только его поймать, чтоб обработчик вызвался, но еще и 
> чтоб системный вызов wait() или waitpid() смогли сработать. 
> Как я понял из приведенного примера это возможно,

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

см также CLONE_PARENT, позволяет сделать fork() таким образом,
что созданный процесс будет иметь того же родителя, что и
текущий. это только в 2.6 и непереносимо, конечно.

idle ★★★★★
()
Ответ на: комментарий от idle

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

Можно. Так раньше делал, но захотелось что-то более изяшное, 
наверное не там ищу пути решения.
А что означает строчка:
  ioctl(fd[0], FIOASYNC, fd);
Я искал 
> man  ioctl_list:
 FIOASYNC
но не нашел такой команды. У меня правда старый дистрибутив. :(
 Может напишите пару строчек, сли не сложно.

anonymous
()
Ответ на: комментарий от anonymous

> А что означает строчка:
> ioctl(fd[0], FIOASYNC, fd);

во-первых, я написал неправильно, нужно:
        int on = 1;
        ioctl(fd[0], FIOASYNC, &on);

позволяет получить сигнал, когда файл (первый аргумент)
готов для чтения/записи. номер сигнала (SIGIO по умолчанию)
задается fcntl(F_SETSIG), получатель - fcntl(F_SETOWN).

idle ★★★★★
()
Ответ на: комментарий от idle

Я правильно понимаю, что строчка:
int on = 1;
ioctl(fd[0], FIOASYNC, &on);
Нужна чтоб научить процесс генерить сигнал при
записи в открытый поток дескриптор которого 'fd'
получен ранее. Для асинхронного чтения из потока,
в обработчике сигнала.
Такая конструкция аналогична select(...) 
Или что-то не так понял.
флаг: 'FIOASYNC' - связан с асинхронными действиями или что-то в этом роде.
я его и не нашел в хелпах.

anonymous
()
Ответ на: комментарий от anonymous

> ioctl(fd[0], FIOASYNC, &on);
> Нужна чтоб научить процесс генерить сигнал при
> записи в открытый поток

сигнал генерит не процесс, а файл. означает, что
файл готов для i/o. это действительно похоже на poll(),
только информация о готовности доставляется сигналом
асинхронно.

> флаг: 'FIOASYNC' - связан с асинхронными
> я его и не нашел в хелпах.

ну должен он где-то быть, у меня маны столетние, не знаю
где. поищите zgrep FIOASYNC /usr/man/man*/*

этот флаг может быть также выставлен с помощью
fcntl(fd, F_SETFL, FASYNC), но это не так удобно.

еще раз повторю, это все равно не позволит вам сделать
wait() на непрямого потомка. см clone(CLONE_PARENT).

idle ★★★★★
()
Ответ на: комментарий от idle

>еще раз повторю, это все равно не позволит вам сделать >wait() на непрямого потомка.

Это я понял, спасибо. спасибо за коментарии и куда смотреть. Буду искать, смотреть.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.