Правильное использование форка, ожидания, выхода и т. Д. - PullRequest
0 голосов
/ 21 апреля 2009

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

Упражнение:
У меня есть матрица с размером [10] [1000000] с целыми числами, и для каждой строки я создаю новый процесс с помощью fork (). Идея каждого процесса состоит в том, чтобы просмотреть все числа для этой конкретной строки и найти конкретное число, а затем напечатать сообщение об этом. Это был первый шаг проблемы, и это сделано. Второй шаг - вывести сумму вхождений этого числа в каждой строке по порядку . И, в конце концов, общее количество вхождений этого числа.

Звонки:
Системные вызовы, которые я могу использовать, описаны в документе для этого упражнения следующим образом:

  • pid_t fork(void);
  • void exit(int status);
  • pid_t wait(int *status);
  • pid_t waitpid(pid_t pid, int *status, int options);

Проблема:
Я понятия не имею, как это сделать, потому что вызов exit() позволяет мне передать только число ниже 256, что если число вхождений больше этого числа? Как мне вернуть такой номер?

Другая проблема:
Я не совсем понимаю разницу между wait() и waitpid() и как / где использовать один над другим. Помимо справочных страниц, есть ли еще документация, где я могу увидеть примеры кода и тому подобное, чтобы лучше их понять? Или кто-то может объяснить мне различия и привести базовый пример, демонстрирующий такие различия?

Ответы [ 2 ]

4 голосов
/ 21 апреля 2009

Используйте waitpid() для последовательного получения статусов выхода дочерних процессов; использование wait() не дает никаких гарантий относительно последовательности, в которой будут извлечены трупы детей.

В Unix состояние выхода ограничено 8 битами, которые могут считаться подписанными или неподписанными программой, получающей данные. Вы также получите 8-битное значение, идентифицирующее номер сигнала и состояние дампа ядра завершенного дочернего элемента. AFAIK, биты состояния или сигнала всегда равны нулю (и часто оба - когда процесс завершается успешно).

Если вы не знаете, что числа, которые должны быть возвращены, меньше 256, тогда выходной статус не подходит. Как уже говорили другие, вы должны использовать какой-то другой IPC в этом случае. Если разрешены только системные вызовы, вы должны сделать вывод, что значения будут меньше 255 или переполнения не имеют значения. Ни один из них не является удовлетворительным как вывод за пределы домашнего задания, но в «реальном мире» вы не ограничены только 4 системными вызовами.

См. Также Коды выхода больше 255? . Обратите внимание, что в Windows диапазон кодов выхода намного больше, но вы не используете системные вызовы, перечисленные в вопросе.


Наблюдение: когда я делаю exit(1), значение в статусе от wait() равно 256; есть ли причина для этого?

Ответ: да. Младшие 8 битов слова состояния кодируют номер сигнала и т. Д .; старшие 8 бит (16-битного) слова состояния кодируют состояние выхода.

См. <sys/wait.h> и макросы WIFEXITED (), WEXITSTATUS () и т. Д.

1 голос
/ 21 апреля 2009

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

Вы упоминаете, что exit () будет разрешать только числа ниже 256. Я очень сомневаюсь, что это так, но вам было бы достаточно написать тестовую программу, чтобы узнать наверняка.

Похоже, это действительно упрощенная версия Map-Reduce . Возможно, вы захотите взглянуть на этот алгоритм, чтобы узнать, как можно еще больше распараллелить программу, и, возможно, получить дополнительный кредит:)

Что касается разницы между wait () и waitpid () - если вы просто хотите дождаться завершения какого-либо из ваших дочерних процессов, вы должны использовать wait (). Если вы хотите дождаться только определенного дочернего процесса или просто хотите проверить, завершился ли дочерний процесс без зависания, вы должны использовать waitpid ().

...