Nano Hash - криптовалюты, майнинг, программирование

Является ли waitpid() атомарной операцией в Linux?

Например, в родительском процессе я развил дочерний процесс и жду дочерний процесс:

int main() {
     setSignal(SIGCHLD, sigchld_handler)
     while(1) {
        // fork some child processes
        myForkFunction()

        waitpid(-1, &status, 0)
     }
}

Более того, у меня есть обработчик сигнала SIGCHLD:

void
sigchld_handler(int sig) {
    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
       // Reap zombie processes
    }    
}

Как видно, waitpid() появляется как в функции main(), так и в функции sigchld_handler(). Мне было интересно, может ли waitpid быть прервано SIGCHLD. Если это может быть прервано SIGCHLD, что тогда произойдет?

У кого-нибудь есть идеи по этому поводу?


  • Почему вы используете WUNTRACED вместо 0 или WNOHANG? WUNTRACED — это очень специальное условие — POSIX waitpid() говорит: WUNTRACED Состояние любых дочерних процессов, указанных в pid, которые остановлены и состояние которых еще не было сообщено с момента их остановки, также должно быть сообщено запрашивающему процессу. (там есть «также», который я пропустил при первом чтении, но даже в этом случае возиться с остановленными/отслеживаемыми процессами необычно.) 04.07.2016
  • Да, WUNTRACED очень странный и, вероятно, не то, что хочет ОП... 04.07.2016
  • @JonathanLeffler Да, ты прав. Спасибо! 04.07.2016
  • Вы исправил это неправильно. Вы должны были изменить его на WNOHANG (а не 0). 0 заставит ваш обработчик сигнала заблокироваться, если у вас есть еще не законченный дочерний элемент. 04.07.2016

Ответы:


1

Спецификация POSIX для waitpid() частично гласит:

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

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

Для всех других условий не указано, будет ли дочерний статус доступен при доставке сигнала SIGCHLD.

Третий из процитированных абзацев, кажется, подразумевает, что вы ходите по тонкому льду. В нем не упоминается «определенная реализация» или что-то подобное — неопределенный означает, что стандарт ничего не говорит о том, что должно произойти, и вы можете получить или не получить какую-либо информацию из документации по конкретной реализации.

В спецификации POSIX содержится много (очень плотно сформулированной) информации. Есть также несколько примеров и обоснование, в котором упоминается sigwait() и sigwaitinfo(). Стоит прочитать всю waipid() страницу. Вероятно, вам следует также прочитать о концепциях сигналов — более подробно чтение. (На днях я тоже этим займусь — когда мне нужно будет узнать о фрагментах сигналов, которые я раньше не рассматривал.)


Почему вы используете WUNTRACED вместо 0 или WNOHANG? WUNTRACED — это очень специальное условие — POSIX говорит:

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

Аналогичные комментарии относятся к WCONTINUED. Эти два флага полезны, когда они вам нужны, но они нужны вам очень редко.

Я предлагаю вам обычно использовать либо 0, либо WNOHANG в третьем аргументе для waitpid().

04.07.2016
  • Спасибо за помощь! Я читал книгу CSAPP, прежде чем задать вопрос. Кажется, что спецификация POSIX - лучшее место для поиска этой информации. Спасибо! 04.07.2016
  • Я покопался в интерфейсе программирования Linux и не нашел не нашел ничего непосредственно относящегося к делу в главе «Мониторинг дочерних процессов», в которой много материала о SIGCHLD и waitpid(), или в паре других мест в той же книге, которую я просматривал. Это далеко не окончательное «это не покрыто», но показательно, что, вероятно, это не так. 04.07.2016

  • 2

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

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

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

    04.07.2016
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..