Форум русскоязычного сообщества Ubuntu


Получить помощь и пообщаться с другими пользователями Ubuntu можно
на irc канале #ubuntu-ru в сети Freenode
и в Jabber конференции ubuntu@conference.jabber.ru

Автор Тема: Вопрос по работе с fork() C++  (Прочитано 2821 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Vlad.V

  • Автор темы
  • Активист
  • *
  • Сообщений: 478
    • Просмотр профиля
Вопрос по работе с fork() C++
« : 18 Сентября 2015, 12:01:00 »
Помогите понять. Есть программа, в цикле опрашивает состояние других программ дабы следить за порядком "на корабле", к этой программе нужно добавить ответвление, которое будет вызываться в определенный момент как функция и проверять сетевые интерфейсы, делать пинги, принимать решения и по окончанию процесса, просто закрываться.  Короче говоря, все это лирика главное то, что программа должна создать дочерний процесс и забыть про него, процесс выполнился и исчез.
Прежде чем написать код, сделаю оговорку, опыт работы с fork() у меня не велик, чтение разных мануалов по fork() не дало понятия как решить мою проблему.

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

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

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

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

Допустим проблему с зомби можно решить вписав где-то в конце цикла 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. Есть ли все таки варианты как седлать так, чтобы основной процесс не ждал ответа от дочернего процесса, а продолжал свою работу, а дочерний процесс, в свою очередь, не становился зомби(не люблю мертвых девушек  ;D)?

Заранее всех благодарю!
« Последнее редактирование: 18 Сентября 2015, 12:04:00 от Vlad.V »

Оффлайн coder-ex

  • Любитель
  • *
  • Сообщений: 71
    • Просмотр профиля
Re: Вопрос по работе с fork() C++
« Ответ #1 : 18 Сентября 2015, 12:26:31 »
советую пока не поняли где ошибка, делать вызов fork(), после чего проверять результат на наличие ошибки и потом уже хендл fork() использовать в дальнейшем коде...
Разработка торговых систем и прикладного ПО для FOREX и FORTS. Программирование на MQL4, MQL5, C++ Qt.

Оффлайн Vlad.V

  • Автор темы
  • Активист
  • *
  • Сообщений: 478
    • Просмотр профиля
Re: Вопрос по работе с fork() C++
« Ответ #2 : 18 Сентября 2015, 12:32:05 »
советую пока не поняли где ошибка, делать вызов fork(), после чего проверять результат на наличие ошибки и потом уже хендл fork() использовать в дальнейшем коде...
Проверка на ошибки, тут вопроссов нет, а что значит хендл fork() ?

Оффлайн coder-ex

  • Любитель
  • *
  • Сообщений: 71
    • Просмотр профиля
Re: Вопрос по работе с fork() C++
« Ответ #3 : 18 Сентября 2015, 18:04:16 »
советую пока не поняли где ошибка, делать вызов fork(), после чего проверять результат на наличие ошибки и потом уже хендл fork() использовать в дальнейшем коде...
Проверка на ошибки, тут вопроссов нет, а что значит хендл fork() ?
fork() что возвращает? идентификатор или -1 если произошла ошибка, что бы узнать, что за ошибка, нужно обнулить переменную ошибки перед вызовом fork(), потом проверить возврат fork() на предмет равенства к -1, если равно -1, то вызываете анализатор ошибок...
вот пример на php - http://habrahabr.ru/post/148688/ там все по полочкам разложено :)
Разработка торговых систем и прикладного ПО для FOREX и FORTS. Программирование на MQL4, MQL5, C++ Qt.

Оффлайн Vlad.V

  • Автор темы
  • Активист
  • *
  • Сообщений: 478
    • Просмотр профиля
Re: Вопрос по работе с fork() C++
« Ответ #4 : 18 Сентября 2015, 18:15:56 »
Спасибо, это все понятно, я не совсем понял как это относится к моей проблемке? fork() всегда возвращает нормальные значения, т.е. 0 потомку, а PID основному процессу. Проблема не в том, что форк не отрабатывает, а в том, что мне либо приходится ждать пока поток завершит свою работу (тормозится и основной процесс) либо никого не ждать, но тогда при каждом цикле основной процесс перерождается и менять свой PID.
Либо я что-то не понял в Вашем совете?  :-\

Оффлайн coder-ex

  • Любитель
  • *
  • Сообщений: 71
    • Просмотр профиля
Re: Вопрос по работе с fork() C++
« Ответ #5 : 21 Сентября 2015, 04:05:02 »
Спасибо, это все понятно, я не совсем понял как это относится к моей проблемке? fork() всегда возвращает нормальные значения, т.е. 0 потомку, а PID основному процессу. Проблема не в том, что форк не отрабатывает, а в том, что мне либо приходится ждать пока поток завершит свою работу (тормозится и основной процесс) либо никого не ждать, но тогда при каждом цикле основной процесс перерождается и менять свой PID.
Либо я что-то не понял в Вашем совете?  :-\
В моем совете призыв к нормальному написанию кода, т.е. как минимум с контролем ошибок :) В ссылке описана проблема в т.ч. и ваша, читайте внимательно и не зацикливайтесь на том, что должны встретиться именно знакомые слова, их скорее всего не будет т.к. это программирование. Уловите там суть вопроса и его решение.
Разработка торговых систем и прикладного ПО для FOREX и FORTS. Программирование на MQL4, MQL5, C++ Qt.

Оффлайн accipiter

  • Новичок
  • *
  • Сообщений: 39
    • Просмотр профиля
Re: Вопрос по работе с fork() C++
« Ответ #6 : 21 Сентября 2015, 11:30:35 »
Ядро посылает родительскому процессу SIGCHLD, когда дочерний завершен, приостановлен или возобновлен. По умолчанию этот сигнал игнорируется, но можно поставить обработчик, а в нем уже вызывать waitpid. Еще waitpid может работать в неблокирующем режиме, для этого нужно передать опцию WNOHANG

Оффлайн Vlad.V

  • Автор темы
  • Активист
  • *
  • Сообщений: 478
    • Просмотр профиля
Re: Вопрос по работе с fork() C++
« Ответ #7 : 21 Сентября 2015, 11:47:12 »
Пока решил вопрос через std::thread, работает именно как мне нужно, одновременно.
Т.е. если я буду делать waitpid(WNOHANG), то основная программа не будет ждать потомка?

 

Страница сгенерирована за 0.076 секунд. Запросов: 26.