Как найти все дочерние процессы?

В проекте на основе Linux, над которым я работаю, мне нужно найти все свои дочерние процессы. Невозможно записывать каждый раз, когда кто-то запускается - их нужно найти по факту. Это должен быть чистый C, и я хотел бы сделать это без чтения /proc. Кто-нибудь знает как это сделать?

7 ответов

Решение

Я нахожу ваш комментарий о том, что нецелесообразно записывать создание процессов как-то странно, но если вы действительно не можете (возможно, потому что вы не знаете, сколько будет создано, и не хотите сохранять reallocпамяти), тогда я бы открыл все файлы, соответствующие глобусу. /proc/[1-9]*/status и искать строку, которая говорит PPid: <num> где <num> был мой идентификатор процесса.

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

Как написано на странице руководства:

pid_t fork(void);

Было бы полезно, если бы вы могли сказать нам, почему вы думаете, что это невозможно.

Вы могли бы использовать попен

Что-то вроде. (Надеюсь, синтаксис достаточно близок)

#include 
#include 
#include 

int main (int argc, char * argv [])
{
    FILE * fp = popen ("ps -C * НАЗВАНИЕ ВАШЕЙ ПРОГРАММЫ ЗДЕСЬ * - формат"%P %p "", "r");
    if (fp == NULL)
    {
        Е ("ОШИБКА!\ п");
    }

    char parentID [256];
    char processID [256];
    while (fscanf (fp, "% s% s", parentID, processID)! = EOF)
    {
         printf ("PID:% s Parent:% s \ n", processID, parentID);

         // Проверяем parentID, чтобы увидеть, что это из вашего процесса
    }

    pclose (FP);

    возврат 1;
}


Вы можете попробовать это

    #include<string.h>
    #include <sys/types.h>
    #include <unistd.h>

    char str[50] = "ps -o pid --ppid ";
    char ppid [7];
    sprintf(ppid,"%d",getpid());
    strcat(str,ppid);
    system(str);

ПРИМЕЧАНИЕ. Этот фрагмент кода должен находиться в родительском процессе.

В принципе ps -o pid --ppid <parent_id> дает pid всех дочерних процессов, чей родитель имеет PID . Теперь мы можем получить PID родительского процесса с помощью getpid(), который возвращает pid_t и неявно преобразуется в целое число.sprintf преобразует его в строку, и мы объединяем результат с str чтобы получить полную команду, которая выполняется system()

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

while (true) {
  // Wait for any child exiting
  int child_status;
  const int child_pid = waitpid(-1, &child_status, 0);
  // check child_status
}

Вы можете проанализировать список процессов (ps -ax?), Который включает идентификатор родительского процесса. Вероятно, это можно сделать с помощью простого сценария оболочки.

Если вы хотите отследить события форка и извлечь дочерние pids для целей отладки, есть несколько способов сделать это, включая:

  • Использование GDB
  • используя strace
  • Использование systemtap
  • Использование соединителей событий ядра (не уверен, что именно это)

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

Но это более полезно для людей, которые хотят поддерживать несколько платформ и / или предпочитают C++.

См. Функцию pids_from_ppid(ppid)https://github.com/time-killer-games/enigma-dev/blob/548dc16e96a2a32f8ad9045a4ee18b0206516e62/ENIGMAsystem/SHELL/Universal_System/Extensions/ProcInfo/procinfo.h

Возвращает строку с идентификаторами каждого дочернего процесса, разделенными вертикальной чертой "|" символ в качестве разделителя.

Пользователям Ubuntu и debian необходимо установить libprocps-dev из-за отсутствия заголовков.

sudo apt-get install libprocps-dev libx11-dev

Зависимость libx11-dev является необязательной, потому что весь код X11 в источнике можно опустить, и на вопрос здесь все равно будет дан ответ, поэтому, если вам нужен путь и поддержка X11, вам следует удалить код, связанный с X11, поскольку он в любом случае не имеет отношения к этому вопросу.

Для тех, кто действительно любит / нуждается в X11 и / или C++, это будет работать из коробки в Windows, Mac, Linux и FreeBSD. Поддержка других BSD не так легко осуществима из-за зависимости от libutil. Но он просто использует sysctl() внутри, поэтому теоретически вы должны иметь возможность скомпилировать исходный код для libutil на других BSD, доступных из репозитория FreeBSD github, а затем связать его после того, как вы его построили.

Другие вопросы по тегам