PDA

View Full Version : [C] Elenco dei processi figli


Sirbako
10-05-2006, 17:36
Salve gente,
è possibilie avere un elenco dei processi figli che ho genrato con il loro status attuale?

71104
11-05-2006, 01:31
sistema operativo? e che intendi di preciso per status?

v1ruz
11-05-2006, 09:03
se sei sotto linux :
puoi memorizzare i vari pid generati dalla fork().
Essa ritorna al padre il pid del processo creato.

per lo status: puoi usare nel padre la sys call waitpid [spero di non sbagliarimi] che secondo a quale opzioni(3 parametro) gli passi ti indica se il processo e' terminato(in quale modo e da quale segnale).

bye

71104
11-05-2006, 11:47
analogamente, se sei su Windows, puoi memorizzare i PID ritornati dalla CreateProcess oppure enumerare i processi con le Toolhelp e prendere solo quelli che hanno il tuo PID come processo padre; per lo "status" forse può esserti utile analizzare il valore di ritorno di GetExitCodeProcess e vedere se è uguale a STILL_ACTIVE.

Sirbako
11-05-2006, 12:23
in linux
solo che a me serve dei processi ancora in esecuzione
(sto facendo una shell, quelli che praticamente sono eseguiti con la & finale)
se faccio un wait mi si blocca, credo..
la variabile status (waitpid(pid,status,opzioni)), è un intero, come si interpreta?

Sirbako
11-05-2006, 12:34
altra cosa, con
pid = waitpid(WAIT_ANY, &status, WNOHANG);
recupero praticamente tutti i figli morti (zombie), credo la funzione nn l'ho fatta io (è il sigchild)..
come posso recuperare tutti i figli indistinatamente?

beppegrillo
11-05-2006, 17:52
La waitpid è una systemcall e per come la chiami puoi usare anche una wait(&status), in modo che ti ritorni i lo status dei figli.
Per avere tutti i pid creati, puoi utulizzare un array di pid globale.

Sirbako
11-05-2006, 22:17
La waitpid è una systemcall e per come la chiami puoi usare anche una wait(&status), in modo che ti ritorni i lo status dei figli.
Per avere tutti i pid creati, puoi utulizzare un array di pid globale.
un wait normale crerebbe dei problemi, mi sa.
mettiamo caso che ho un vettore di figli pid, come interrogo il loro status?
waitpid(vpid[i],&status,0)?

Andlea
12-05-2006, 12:46
La prima soluzione che mi viene è molto poco elegante, ma dovrebbe funzionare
nei figli associa ad un segnale un handler che risponde al padre via pipe o altro.
Quando vuoi interrogare un figlio gli mandi un segnale e leggi dalla pipe, se ti ritorna 0(ricordati di chiudere la pipe prima di chiudere il figlio) sai che ha finito e puoi fare una wait, alternativamente puoi farti mandare qualche variabile che rappresenta lo stato che ti interessa, o eventualmente un semplice acknowledge.

Sirbako
12-05-2006, 18:33
La prima soluzione che mi viene è molto poco elegante, ma dovrebbe funzionare
nei figli associa ad un segnale un handler che risponde al padre via pipe o altro.
Quando vuoi interrogare un figlio gli mandi un segnale e leggi dalla pipe, se ti ritorna 0(ricordati di chiudere la pipe prima di chiudere il figlio) sai che ha finito e puoi fare una wait, alternativamente puoi farti mandare qualche variabile che rappresenta lo stato che ti interessa, o eventualmente un semplice acknowledge.
come si manda un segnale? :confused:

Qu@ker
12-05-2006, 18:34
Usa kill(). Vedi, ad es., qui (http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC18).

Andlea
12-05-2006, 20:25
come si manda un segnale? :confused:
aia
si manda con kill, presumo che tu non sappia nemmeno come gestire un segnale, ovvero con signal
nel man di linux trovi tutto

saluti

Sirbako
12-05-2006, 23:48
aia
si manda con kill, presumo che tu non sappia nemmeno come gestire un segnale, ovvero con signal
nel man di linux trovi tutto

saluti
si ma con kill recupero se è attivo o meno.
a me serve sapere se è running sleep ecc..
devo implementare il jobs per capirsi..

Qu@ker
13-05-2006, 08:51
Dai un'occhiata qui (http://www.erlenstar.demon.co.uk/unix/faq_8.html#SEC90).

Sirbako
13-05-2006, 10:13
Dai un'occhiata qui (http://www.erlenstar.demon.co.uk/unix/faq_8.html#SEC90).
a me interssa sapere se il processo è in stato di sleeping running ecc.. il problema è che quello nn riesce a dirmelo

Sirbako
13-05-2006, 12:12
allora va solo running exit stop. dello sleep nn so.
mi sapete dire una cosa? se do crtl+z mando in stop il programma, come lo ritiro su?

Qu@ker
13-05-2006, 12:14
Pfff... tratto dal link che ho postato sopra.
Qui c'è, fondamentalmente, tutto quello che ti serve. Ovviamente lo devi adattare e integrare.

int check_children()
{
pid_t pid;
int status;
int count = 0;

while ((pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0)
{
if (pid == bgjob && !WIFSTOPPED(status))
bgjob = -1;

++count;

if (WIFEXITED(status))
fprintf(stderr,"Process %ld exited with return code %d\n",
(long)pid, WEXITSTATUS(status));
else if (WIFSIGNALED(status))
fprintf(stderr,"Process %ld killed by signal %d%s\n",
(long)pid, WTERMSIG(status),
WCOREDUMP(status) ? " (core dumped)" : "");
else if (WIFSTOPPED(status))
fprintf(stderr,"Process %ld stopped by signal %d\n",
(long)pid, WSTOPSIG(status));
else
fprintf(stderr,"Unexpected status - pid=%ld, status=0x%x\n",
(long)pid, status);
}

return count;
}

Sirbako
13-05-2006, 12:16
Pfff... tratto dal link che ho postato sopra.
Qui c'è, fondamentalmente, tutto quello che ti serve. Ovviamente lo devi adattare e integrare.

....

si sistemato, solo che se faccio partire un prog in background (cioè con &) mi ritorna come exit 0, ma ho sistemato.
per lo sleeping niente?

Qu@ker
13-05-2006, 14:14
Forse il modo più semplice, se ho capito bene quello che intendi, considerato che dovresti avere l'elenco dei PID, potrebbe essere qualcosa del genere:

jcd@big:~$ export PID=4419
jcd@big:~$ cat /proc/$PID/status | grep State
State: S (sleeping)
jcd@big:~$

Sirbako
16-05-2006, 10:28
ho ancora dei problemi.. dopo li posto.. cmq non funziona molto bene

Sirbako
16-05-2006, 16:43
problema:


int i,pid,status;
for(i=0;i<tot;i++){
pid=figli[i].pid;
if (kill(pid,0)!=0) rem_figlio(pid);
else
if (waitpid(pid, &status, (WNOHANG | WUNTRACED))!=0){
if (WIFEXITED(status)){
if (WEXITSTATUS(status)!=0)
printf("[%d]\t%s\t%ld\tEXIT%d\n",i,figli[i].cmd,(long)pid, WEXITSTATUS(status));
}
else if (WIFSIGNALED(status))
fprintf(stderr,"[%d]\t%s\t%ld KILLED %d%s\n",
(long)pid, WTERMSIG(status),
WCOREDUMP(status) ? " (core dumped)" : "");
else
if (WIFSTOPPED(status))
printf("[%d]\t%s\t%ld\tSTOP%d\n",i,figli[i].cmd,(long)pid, WSTOPSIG(status));
else
printf("[%d]\t%s\t%d\tNON SO\n",i,figli[i].cmd,(long)pid, status);
}
else
printf("[%d]\t%s\t%d\tRUNNING\n",i,figli[i].cmd,(long)pid, status);
}
}



finche c sono figli nel vettore, fai il wait (quello sopra) sul pid direttametne, se torna 0 è running, sennò controlla.
ora:

--stefano@ubuntu:~/shell$gimp &
[0] gimp 11763 0

fin qui ok, aggiunge il processo alla lista

--stefano@ubuntu:~/shell$jobs
[0] gimp 11763 RUNNING

l'output è esatto

--stefano@ubuntu:~/shell$gimp

[1] gimp 11766 0
faccio partire gimp, do ctrl+z (che manda un sigstop al pid del figlio, che quindi si stoppa e il controllo torna al padre); aggiunge il figlio corrente alla lista dei figli
tutto apposto per questo pezzo

--stefano@ubuntu:~/shell$jobs
[0] gimp 11763 STOP20
[1] gimp 11766 RUNNING

primo problema: è il secondo che deve essere STOP, il primo è running

--stefano@ubuntu:~/shell$jobs
[0] gimp 11763 RUNNING
[1] gimp 11766 RUNNING

al secondo giro sono addirittura tutti e due running..
qualcuno sa come risolvere??? :muro: :muro: :mc: :mc: