Работе с fork() C++

Модератор: Модераторы разделов

Ответить
VladVol
Сообщения: 142
ОС: KUbuntu

Работе с fork() C++

Сообщение VladVol »

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

Вот как я пытаюсь это сделать:

Код: Выделить всё

while(status == "start")
{
    //тут никому неинтересный код
    // тут вызываю функцию interfaces через форк
    int inter_pid(fork()); // в этот момент программа раздваивается и главный процесс получает ID потомка, а потомок получает 0, если все прошло успешно.

    if(inter_pid == 0)  // т. е. если ты потомок
        interfaces(); //выполни функцию interfaces;

    //далее опять идет неинтересный код, небольшая отсрочка и все пошло сначала.
}


Функция interfaces заканчивается "exit(0);", используя такой код, все работает, вот только функция interfaces, по окончанию, становится зомби ожидая пока главный процесс спросит: "Ну как там дела в школе? Сегодня получил 0 или 1 или еще что-то получил?" А если родителю плевать на "оценки в школе"? В моем случае это именно так.

Допустим проблему с зомби можно решить вписав где-то в конце цикла wait() или waitpid(), но тогда теряется весь смысл fork(). Мне нужно параллельное выполнение главного процесса и процесса потомка.
Представим ситуацию, "упала" программа, за которой наблюдает основной процесс в цикле и в этот же момент потомок затупил с пингом, ну не может он получить ответ, но пытается. В такой ситуации, если использовать wait или waitpid "упавшая" программа будет поднята только тогда, когда дочерний процесс расскажет "о делах в школе", а если я извращенец и у меня в функции interfaces() при отсутствие пинга запускается компиляция ядра или еще какая-то хрень которая затормозит основной процесс на долгое время? Короче ждать ответа от дочернего процесса — не вариант, зомбаки — опять таки не вариант.

Можно поступить по другому:

Код: Выделить всё

while(status == "start")
{
    //тут никому неинтересный код
    // тут вызываю функцию interfaces через форк
    pid_t inter_pid(fork());
    if(inter_pid > 0)  // т. е. если ты родитель
        interfaces(); //выполни функцию interfaces;

    //далее опять идет неинтересный код, небольшая отсрочка и все пошло сначала.
}


В данном случае все работает как по маслу, основной процесс запускает функцию interfaces(), а потомок продолжает основной цикл. Основной процесс завершил функцию interfaces() и закрылся(без зомби и wait), дочерний процесс, который уже стал основным продолжает цикл.

Спасибо всем тем, кто потратил свое время и дочитал до этих строк. Так вот суть вопроса:
1. Нормально ли то, что при использовании последнего кода процесс постоянно "перерождается" и соответственно постоянно меняет свой PID?
2. Есть ли все таки варианты как седлать так, чтобы основной процесс не ждал ответа от дочернего процесса, а продолжал свою работу, а дочерний процесс, в свою очередь, не становился зомби(не люблю мертвых девушек :laugh: )?

Заранее всех благодарю!
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Работе с fork() C++

Сообщение Bizdelnick »

Можно использовать waitpid() с флагом WNOHANG в цикле.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4455
Статус: GNU generation
ОС: Debian GNU/Linux

Re: Работе с fork() C++

Сообщение Rootlexx »

Bizdelnick писал(а):
18.09.2015 17:30
Можно использовать waitpid() с флагом WNOHANG в цикле.

Помимо этого можно:
* Заигнорировать SIGCHLD. Пожалуй, самый простой вариант, но может не работать вне Linux.
* Вызывать waitpid в обработчике SIGCHLD.
* Использовать потоки вместо fork.
* Делать двойной fork: дочерний процесс запускает рабочий дочерний процесс, после чего немедленно завершается, и его статус тут же прочитывается родителем; второй же дочерний процесс становится потомком init, который уже подчистит зомби. :crazy:
Спасибо сказали:
Ответить