2009-06-17 45 views
11

En un proyecto basado en Linux en el que estoy trabajando, necesito poder encontrar todos mis procesos hijo. No es factible registrar cada vez que se inicia uno; deben encontrarse después del hecho. Esto necesita ser C puro, y me gustaría hacerlo sin leer/proc. ¿Alguien sabe como hacer esto?¿Cómo encontrar todos los procesos secundarios?

+0

por 'pura C' Estuve incluyendo "no analizando la salida de comando". – c4757p

+0

¿Por qué no es factible? Esta es la forma más limpia y eficiente de hacerlo. – Duck

+0

¿Se opone a escribir un LKM que anulará una de las llamadas al sistema no utilizadas?Si es así, sería trivial escribir una pequeña llamada al sistema que lo haga por usted. – FreeMemory

Respuesta

2

Encuentro su comentario de que no es fea Es posible grabar la creación de procesos para que sea impar, pero si realmente no puede (posiblemente porque no sabe cuántos se crearán y no quiere tener que mantener realloc en la memoria), entonces probablemente abriría todos los archivos que coinciden con el glob /proc/[1-9]*/status y busque la línea que dice PPid: <num> donde <num> era mi identificador de proceso.

+0

Dijo que quería hacerlo sin leer/proc ... – Polaris878

+0

Y luego aceptó mi respuesta, así que creo que cambió de opinión después de ver lo fácil que sería. –

+5

Una razón perfectamente justa por la cual es posible que no puedas registrar la creación de cada proceso secundario: si sabes que una biblioteca organiza procesos y no te proporciona sus PID. – tomjakubowski

1

Puede analizar una lista de procesos (ps -ax?) Que incluye el ID del proceso principal. Esto probablemente podría hacerse con un simple script de shell.

+0

Dijo pure c;). Aunque lo hice de esa manera con éxito. –

+0

¿Todavía cuenta como C puro si ejecuta un comando de shell desde él? – sangretu

+0

@sangretu No, incluso si es C shell. ;) – Duck

3

Puede usar popen

Algo así como. (Esperemos que la sintaxis es lo suficientemente cerca)

 
#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 

int main(int argc, char *argv[]) 
{ 
    FILE *fp = popen("ps -C *YOUR PROGRAM NAME HERE* --format '%P %p'" , "r"); 
    if (fp == NULL) 
    { 
     printf("ERROR!\n"); 
    } 

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

     // Check the parentID to see if it that of your process 
    } 

    pclose(fp); 

    return 1; 
} 


+0

bleh, la misma respuesta que sangretu's. –

+0

Byron, te voté porque probablemente tengas la mejor respuesta para lo que es la pregunta ahora que ps no es una opción. Sin embargo, espero que no me hayas votado por b/c, mi respuesta es la misma que la de sangretu con más detalles. Estábamos separados por 2 minutos y me llevó tiempo escribir el pseudocódigo inicial. Desde entonces he editado para proporcionar un código más detallado que funciona. –

+0

Gracias, buen código. –

4

Por lo general, es totalmente factible para registrar procesos hijo cada vez que inicie una. convenientemente, el proceso principal pasa el valor pid del proceso hijo como el valor de retorno de la llamada de horquilla que lo crea.

Como la página del manual dice:

pid_t fork(void); 

Sería de gran ayuda si usted podría decirnos por qué cree que no es factible.

+0

Supuse que tenía una buena razón. Pero estás en lo correcto. Por lo general, es bastante trivial obtener esa información. – sangretu

0

Si desea realizar un seguimiento de eventos de horquilla y extraer los PID niño con fines de depuración, hay un número de maneras de hacerlo, incluyendo:

  • Usando BGF
  • usando strace
  • Usando systemtap
  • Uso de conectores de eventos del kernel (no sé qué es esto exactamente)
3

Usted podría intentar esto

#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); 

NOTA: Esta pieza de código tiene que estar en el proceso padre

Básicamente ps -o pid --ppid <parent_id> da el pid de todos los procesos hijo cuyo padre tiene PID. Ahora, podemos obtener el PID del proceso padre utilizando el getpid(), que devuelve pid_t y se convierte implícitamente en un entero. El formato de archivo lo convierte en una cadena y concatenamos el resultado con str para obtener el comando completo que se ejecuta mediante system()

+0

¿'system (str)' muestra el resultado en la consola y también quiero que todos los identificadores en una matriz –

0

Si usted está tratando de conseguir todos los procesos hijo con el propósito muy específico de esperar a que salga, puede utilizar waitpid (-1, ...):

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

puedo usar su solución para mostrar el estado del proceso en segundo plano en mi shell. Pero, cuando el loop se rompe? – alhelal

Cuestiones relacionadas