PDA

View Full Version : [C] SEGNALI mettere in pausa un gruppo di processi


FNF-fabius
04-09-2008, 15:48
Salve a tutti,
ho un problema riguardante la gestione dei segnali sotto Unix.
A partire da un processo padre che si forka n volte devo tramite segnali mettere in pausa il padre stesso e tutti gli n figli attivi in un dato istante. La pausa deve essere lunga un numero di secondi arbitrario, a discrezione dell'uutente.
Io ho impostato in C le seguenti righe di codice ma c'e' qualcosa ke mi sfugge, i processi vanno in pausa ma al momento di riprendere l'attivita' il programa termina al posto di continuare dal punto in cui si era fermato.

nel processo padre inserisco un gestore di SIGTSTP esattamente prima di iniziare il ciclo di fork degli intermediari - signal (SIGTSTP, gest1);

il segnale viene cosi' gestito dal processo padre

scanf("%d",&pausa); //si legge il numero arbitrario di secondi per la pausa


killpg(INTERM,SIGSTOP); //mando un SIGSTOP ai processi figli che ho radunato sotto il gruppo INTERM


sighold(SIGALRM);

alarm(pausa);

sigpause(SIGALRM);
//metto in pausa il padre in attesa di un SIGALRM
//e invio un SIGALRM dopo "pausa" secondi
killpg(INTERM,SIGCONT);

//infine quando il padre e' risvegliato da SIGALRM invia un SIGCONT ai processi figli affinche' riprendano l'esecuzione.

Un problema che ho rilevato e' che non riesco nel codice dei processi figli ad impostare correttamente il gruppo:

int group=setpgid(getpid(), INTERM);//assegno il groupID

questa ritorna sempre -1. Qualcuno sa dirmi come mai?
C'e' un'altra forma per raggruppare processi in modo da inviare un segnale a tutto un gruppo?

Grazie

aleksay
08-09-2008, 14:45
salve a tutti
ho lasciato maturare un pochino questo blog sperando che qualcuno desse un aiutino
perche anche io ho lo stesso identico problema.....

groupID = setpgid(0,getpid());

questa riga fallisce stampando :not owner
nella console degli errori

please sono in alto mare!!!!:muro: :muro: :muro:

xciaoatuttix
08-09-2008, 15:41
ciao ho letto il post ma non ho capito niente :D
se mi spieghi in breve solo cosa vuoi fare ti aiuto io se riesco :)

aleksay
08-09-2008, 16:10
ciao xciaoatuttix!!!!

praticamente il programma sarebbe un agenzia viaggi che alla pressione di CTRL-Z
va in sciopero per un tot di secondi (inseriti da tastiera) e poi continua a lavorare.

questo implica che un programma invii a tutti i suoi figli un SIGSTOP e poi
senza fare attesa attiva invii agli stessi processi un SIGCONT....

:mc: :mc:

xciaoatuttix
08-09-2008, 16:48
allora questo programma funziona come dici:
lavora e quando riceve il segnale SIGTSTP ( Ctrl+z ) aspetta x secondi inseriti da tastiera.
iniziamo da qui e poi vediamo che altro ti serve :)
il discorso sui figli non l'ho capito. Quanti figli si devono creare ? vanno tutti sotto lo stesso gruppo ? anche il padre fa parte del gruppo? ecc :D

#include <stdio.h>
#include <fcntl.h>
#include <signal.h>

void sighandler(int);

main() {

signal(SIGTSTP,sighandler);

while(1){
printf("sto lavorando\n");
sleep(1);

}

}


void sighandler(int sig)
{int x;
printf("segnale ricevuto. Quanti secondi devo aspettare? \n");
scanf("%d",&x);
sleep(x);
}

aleksay
08-09-2008, 17:59
il mio problema e che la sleep() effettua una attesa attiva...occupa la cpu invece dovrebbe sospendersi...e poi sarebbe troppo facile!!! :p

il processo padre e un demone che crea sei figli alla volta che nascono e muoiono in continuo...ad un certo punto (pressione di CTRL-Z) i figli si devono sospendere senza che pero venga sospeso il padre...se no non posso piu risvegliare niente...

per quanto riguarda la gestione dei gruppi tutti i figli e il padre fanno parte dello stesso gruppo che ha come ID il pid del padre....comportamento di default perche come diceva FNF-fabius le setpgid() falliscono sempre e cmq :muro:

altra piccola cosa.. se eseguo queste tre righe:

sighold(SIGALRM);
alarm(pausa);
sigpause(SIGALRM);

l'ultima istruzione mi termina il programma....percheee?!?!?!?????:muro: :muro: :muro:

xciaoatuttix
08-09-2008, 19:56
non capisco perche ma anche a me fallisce mi spiace :(

pensavo bastasse avviare il programma come superuser e invece dice sempre che l'operazione non è permessa :doh: