View Full Version : [C] Elenco dei processi figli
Salve gente,
è possibilie avere un elenco dei processi figli che ho genrato con il loro status attuale?
sistema operativo? e che intendi di preciso per status?
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
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.
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?
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.
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)?
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.
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:
Usa kill(). Vedi, ad es., qui (http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC18).
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
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..
Dai un'occhiata qui (http://www.erlenstar.demon.co.uk/unix/faq_8.html#SEC90).
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
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?
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;
}
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?
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:~$
ho ancora dei problemi.. dopo li posto.. cmq non funziona molto bene
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:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.