ребенок ждет другого ребенка - PullRequest
3 голосов
/ 29 апреля 2011

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

Ответы [ 4 ]

1 голос
/ 29 апреля 2011

Да.Просто выделите процесс, который нужно наблюдать, из процесса, чтобы посмотреть его .

if (fork() == 0) {
    // we are the watcher
    pid_t watchee_pid = fork();
    if (watchee_pid != 0) {
        // wait and/or handle timeout
        int status;
        waitpid(watchee_pid, &status, WNOHANG);
    } else {
        // we're being watched. do stuff
    }
} else {
    // original process
}

Чтобы подчеркнуть: есть 3 процесса.Оригинал, процесс наблюдателя (который обрабатывает тайм-аут и т. Д.) И фактический наблюдаемый процесс.

0 голосов
/ 29 апреля 2011

Единственные процессы, которые вы можете wait использовать, это ваши собственные прямые дочерние процессы - не братья и сестры, не ваши родители, не внуки и т. Д. В зависимости от потребностей вашей программы решение Мэтта может работать для вас. Если нет, вот некоторые другие альтернативы:

  • Забудьте об ожидании и используйте другую форму IPC. Для надежности это должно быть что-то такое, при чем неожиданное завершение ожидаемого вами процесса приводит к получению вами события. Лучшее, что я могу придумать, - это открыть pipe, который совместно используется обоими процессами, и передать конец записи канала процессу, который вы хотите ждать (убедитесь, что другие процессы не поддерживают конец записи открытым!). Когда процесс, содержащий конец записи, завершается, он будет закрыт, и конец чтения будет указывать EOF (read будет блокировать его до тех пор, пока конец записи не закроется, а затем вернет чтение нулевой длины).

  • Забудьте об IPC и используйте темы. Одним из преимуществ потоков является то, что атомарность "процесса" сохраняется. Невозможно уничтожить отдельные потоки или иным образом завершить их вне контроля вашей программы, поэтому вам не нужно беспокоиться о состоянии гонки с идентификаторами процессов и распределением общих ресурсов в глобальном пространстве имен системы (объекты IPC, имена файлов, сокеты). , так далее.). Все примитивы синхронизации существуют исключительно в адресном пространстве вашего процесса.

0 голосов
/ 29 апреля 2011

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

  pid_t pid = fork();

  if (pid == -1) {
    printf("fork: %s", strerror(errno));
    exit(1);
  } else if (pid > 0) {
    /* parent process */
    int i = 0;
    int secs = 60; /* 60 secs for the process to finish */
    while(1) {
        /* check if process with pid exists */
        if (exist(pid) && i > secs) {
          /* do something accordingly */
        }
        sleep(1);
        i++;
    }
  } else {
    /* child process */
    /* child logic here */
    exit(0);
  }

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

exist(pid) относится к функции, для которой вам нужен код, который просматривает proc/pid, где pid - процессid дочернего процесса.

При желании вы можете реализовать функцию exist(pid), используя другие библиотеки, предназначенные для извлечения информации из каталога /proc, например procps

0 голосов
/ 29 апреля 2011

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

Код может сильно различаться в зависимости от C или C ++, вам нужно выбрать какой. Если C ++, вы можете использовать boost::interprocess для этого - что имеет много примеров использования общей памяти. Если C, то вам придется собрать это вместе, используя собственные вызовы для вашей ОС - опять же это должно быть довольно просто - начните с shmget()

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