2009-06-17 14 views
11

In un progetto basato su Linux su cui sto lavorando, devo essere in grado di trovare tutti i miei processi figli. Non è possibile registrare ogni volta che si inizia: devono essere trovati dopo il fatto. Questo deve essere puro C, e mi piacerebbe farlo senza leggere/proc. Qualcuno sa come fare questo?Come trovare tutti i processi figli?

+0

Con 'puro C' Ero un po 'inclusivo di' non analizzare l'output del comando '. – c4757p

+0

Perché non è fattibile? Questo è di gran lunga il modo più pulito ed efficiente per farlo. – Duck

+0

Sei contrario alla scrittura di un LKM che sovrascriverà una delle chiamate di sistema inutilizzate?Se è così, sarebbe banale scrivere una piccola chiamata di sistema che lo farà per te. – FreeMemory

risposta

2

trovo il tuo commento che non è FEA è possibile registrare la creazione di processi per essere dispari, ma se proprio non si può (forse perché non si sa quanti ne verranno creati e non si vuole mantenere la memoria realloc), probabilmente aprirò tutti i file che corrispondono al glob /proc/[1-9]*/status e cercare la riga che dice PPid: <num> dove <num> era il mio ID di processo.

+0

Ha detto che voleva farlo senza leggere/proc ... – Polaris878

+0

E poi ha accettato la mia risposta, quindi credo che abbia cambiato idea dopo aver visto quanto sarebbe stato facile. –

+5

Un motivo perfettamente giusto per cui potresti non essere in grado di registrare la creazione di ogni processo figlio: se sai che un fork di librerie viene elaborato e non ti dà i PID. – tomjakubowski

1

È possibile analizzare un elenco di processi (ps -ax?) Che include l'ID del processo principale. Questo potrebbe probabilmente essere fatto con un semplice script di shell.

+0

Ha detto puro c;). L'ho fatto in quel modo con successo però. –

+0

Conta ancora come C pura se si esegue un comando di shell da esso? – sangretu

+0

@sangretu No - anche se è C shell. ;) – Duck

3

È possibile utilizzare popen

Qualcosa come. (Speriamo che la sintassi è abbastanza vicino)

 
#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, stessa risposta di sangretu. –

+0

Byron, ti ho votato perché probabilmente hai la migliore risposta per la domanda ora che ps non è un'opzione. Però, spero che non mi abbia votato b/c la mia risposta è la stessa di sangretu con più dettagli. Eravamo a 2 minuti di distanza e mi ci è voluto tempo per scrivere lo pseudo-codice iniziale. Da allora ho modificato per fornire un codice più dettagliato che funzioni. –

+0

Grazie, bel codice. –

4

solito è del tutto possibile per registrare processi figli ogni volta che si avvia uno. convenientemente, il processo padre viene passato il valore pid del processo figlio come valore di ritorno della chiamata a forcella che lo crea.

come pagina man dice:

pid_t fork(void); 

Sarebbe utile se ci si potrebbe dire perché si pensa che non è fattibile.

+0

Ho pensato che avesse una buona ragione. Ma hai ragione. Di solito è piuttosto banale ottenere queste informazioni. – sangretu

0

Se si vuole tracciare gli eventi forcella ed estrarre pid bambini a scopo di debug, ci sono una serie di modi per farlo, tra cui:

  • Utilizzando GDB
  • usando strace
  • Utilizzando systemtap
  • tramite connettori eventi del kernel (non so cosa si tratta esattamente)
3

Si potrebbe provare questo

#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: Questo pezzo di codice deve essere nel processo padre

Fondamentalmente ps -o pid --ppid <parent_id> dà il PID di tutti i processi figli il cui genitore ha PID. Ora, possiamo ottenere il PID del processo del genitore usando il getpid(), che restituisce pid_t e viene convertito implicitamente in un integer.sprintf lo converte in una stringa e concateniamo il risultato con str per ottenere il comando completo che viene eseguito da system()

+0

'system (str)' mostra l'output alla console e voglio anche che tutti gli id ​​in un array –

0

Se si sta cercando di ottenere tutti i processi figli per lo scopo ben preciso di aspettare per loro di uscire, è possibile utilizzare 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

Posso usare la tua soluzione per mostrare lo stato del processo in background nella mia shell. Ma quando il ciclo si interrompe? – alhelal

Problemi correlati