|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
[C] - signal e wait
Continuo a rompere le scatole sull'IPC
![]() Supponiamo di avere un processo padre P che genera 2 gruppi di processi figli logicamente diversi, diciamo gruppo f1 e f2. Se a un certo punto P riceve un segnale USR1 deve: 1)Inviare un segnale di terminazione ai processi del gruppo f1 e ASPETTARE che terminino... 2)Inviare un segnale di terminazione immediata ai processi del gruppo f2. Inizialmente avevo pensato di usare due array che tenessero traccia del pid dei due gruppi. Ma, almeno per il gruppo f2 non è detto che esistano dei processi (potrbbero esser già terminati). Possono venirmi utile la syscall setpgid e getpgid ?? |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Mi sembra sensato.
Ti consiglio di gestire i due gruppi di processi da due processi leader di gruppo (v. man setsid)
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
Stavo pensando al primo gruppo di processi figli... devo necessariamente usare un vettore, perchè dovrà esserci una sequenza di
kill (f1) wait(f1) ... kill (fn) wait(fn) Non posso mandare una kill a tutti e poi una wait per tutti!Perciò poi avendo terminato tutti gli fi, potrei lanciare una kill(0) che mi ucciderebbe immediatamente tutti i restanti eventuali processi figli (che hanno lo stesso group id del padre!) fila? ![]() |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Io articolerei il problema in questo modo:
- Per ogni program group crei un leader. Questo leader tiene un contatore di quanti processi sono aggiunti al gruppo. - Ogni volta che crei un processo, questo si deve spostare sul corretto gruppo di appartenenza, e manda un segnale (ad es. SIGURS1) al group leader. Il group leader, in corrispondenza di un SIGUSR1, incrementa il contatore dei processi. - Quando devi terminare i processi di un certo gruppo, mandi un segnale (ad es. SIGQUIT) a tutti i processi del gruppo, tramite killpg. Questo segnale deve essere ignorato dal group leader, e intercettato dagli altri processi. Ogni volta che un processo muore, prima di morire manda un segnale (ad es. SIGUSR2) al group leader (non so se cambiando gruppo, la morte di un processo generi automaticamente un SIGCHLD al group leader -- non ho mai provato, ma dovrebbe essere così). - Il group leader intercetta i SIGUSR2 (o SIGCHLD, se funziona come penso) e decrementa il contatore dei processi - Quando il contatore dei processi arriva a 0, notifica con un segnale al processo padre che tutti i processi del gruppo sono terminati. E' solo una via, potresti pensare altre soluzioni.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 Ultima modifica di ilsensine : 08-04-2004 alle 14:37. |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
Allora, vediamo di spiegare meglio il problema: il primo gruppo di processi è composto da un numero n noto a priori. Tutti gli n processi di qusto gruppo vivono dall'inizio alla fine della vita del padre.
Prima di morire il padre deve killarli (attendendo la loro terminazione). POI deve killare eventuali altri processi servi (appartenenti al gruppo 2) senza attenderne la terminazione. Il discorso dei leader di gruppo è interessante, ma non credo debba rientrare nella soluzione di questo progettino, non essendo stato tema di studio. |
![]() |
![]() |
![]() |
#6 | |||
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Quote:
Quote:
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|||
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
Il fatto è che sono tutti figli! Praticamente i primi n processi figli sono lanciati all'inizio e poi possono richiedere al Padre un servizio, e questo si forcherà per fornirglielo... Quindi io non ho solo n processi figli da killare, ma quegli n + eventuali altri servi.
Il termine "gruppo" l'ho usato io, non o se questo problema può rientrare in questa categoria. Codice:
for (i=0; i<n; i++) { printf("Invio segnale di terminazione al processo%d \n",pid_processi[i]); kill(pid_processii[i],SIGKILL); printf("Attendo che %d termini \n",pid_processi[i]); waitpid(pid_processi[i],&status,0); } free(pid_processi); *pid_processi=NULL; //killa eventuali altri figli(i servi) IMMEDIATAMENTE kill(0,SIGKILL); // mi killa tutti i processi con lo stesso PGID del padre, ovvero tutti i figli restanti! |
![]() |
![]() |
![]() |
#8 | ||
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
![]() Codice:
for (i=0; i<n; i++) kill(pid_processi[i],SIGKILL); for (i=0; i<n; i++) waitpid(pid_processi[i],&status,0); Quote:
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
||
![]() |
![]() |
![]() |
#9 | |||
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
Quote:
Quote:
Quote:
|
|||
![]() |
![]() |
![]() |
#10 | |||
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Quote:
Quote:
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|||
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
ovvero se mi metto in wait di un processo che non esiste più non ho problemi? se ne accorge ed esce ?
![]() Quote:
![]() |
|
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
Si il gpid del padre è settato al pid...perciò non posso usare una kill(0) o una kill (-pid) perchè morirebbe anche il Padre...
Approfondisco il discorso sul setsid... |
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Jul 1999
Città: Torino
Messaggi: 2221
|
Fatto!
![]() Per il secondo gruppo di processi creo un gruppo con un leader), tengo traccia del gpid del gruppo e poi li killo con killpg ![]() Codice:
#include<stdio.h> #include<errno.h> #include<signal.h> #include<sys/types.h> main (){ int i,f; pid_t *pid_processi=NULL; char *fil_num; int sid; pid_processi=(int *)malloc(3*sizeof(pid_t)); fil_num=(char *)malloc(2*sizeof(char)); printf("PADRE! gpid: %d -- pid: %d -- sid: %d\n",getpgid(),getpid(),getsid()); for (i=0; i < 3; i++) { f = pid_processi[i] = fork(); sprintf(fil_num,"%d",i); printf("fil_num: %d ",i,fil_num); if (f == 0) execl("./s","./s",NULL); //n e fil_num sono gl iargomenti passati al filosofo } for (i=0; i < 3; i++) //printf("pid_processi[%d]: %d ",i,pid_processi[i]); printf("\n"); f = sid = fork(); if (f==0){ setsid(); //nuovo gruppo! printf("SERVO LEADER! gpid: %d -- pid: %d -- sid: %d\n",getpgid(),getpid(),getsid()); i=0; while(i< 3) { i++; f = fork(); if (f==0){ //ereditano i gpgid del leader printf("SERVO! gpid: %d -- pid: %d -- sid: %d\n",getpgid(),getpid(),getsid()); system("sleep 5"); exit(0); } } exit(0); } for (i=0; i < 3; i++) kill(pid_processi[i],SIGKILL); for (i=0; i < 3; i++) wait(pid_processi[i]); printf("PADRE! gpid: %d -- pid: %d -- sid: %d\n",getpgid(),getpid(),getsid()); killpg(sid,SIGKILL); printf("termino anche io!\n"); exit(0); } |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 21:40.