Max
2014-07-14 09:38:51 UTC
Ho provando a fare questo esercizio:
Si progetti in ambiente Unix/C la seguente interazione di processi:
- il sistema consiste di N+1 processi che interagiscono a due a due
tramite una delle N pipe disponibili: la pipe p_i è utilizzata in lettura
dal processo P_i e in scrittura dal processo P_i-1 ;
- il processo P_0 inoltra il proprio pid nella pipe e attende l'arrivo di un
segnale;
- ogni processo P_i (con i<N) preleva il messaggio dalla pipe p_i e lo
scrive nella pipe p_i+1 ;
- il processo P_N, ricevuto il pid di P_0, provvede ad inviargli un
segnale SIGUSR1.
Consigli del docente del corso:
1)Abbiamo un processo padre e N suoi processi figli
2)La struttura dati che deve contenere le pipe deve essere una matrice
di N righe e due colonne.
Questo il mio tentativo:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#define N 10
void Gestione(int s){
printf("Segnale ricevuto\n");
}
int main()
{
int i,pid,ptoken;
int matfd[N][2];
for(i=0;i<N;i++)
pipe(matfd[i]); //creo le N pipe su cui far passare il pid del padre
for(i=0;i<N;i++){
pid=fork();
if(pid==-1) {perror("Errore fork\n"); _exit(1);}
if (pid==0) {
printf("Processo P%d\t",i+1); close(matfd[i][1]); close(matfd[i+1][0]);
//chiudo i "lati" delle pipe su cui non devo leggere/scrivere
read(matfd[i][0],&ptoken,sizeof(int)); printf("Ptoken: %d\n",ptoken);
if (i==(N-1)) {kill(ptoken,SIGUSR1); _exit(0);} //ossia sono l'ultimo
processo figlio e mando il segnale al padre
else {write(matfd[i+1][1],&ptoken,sizeof(int)); _exit (0);}
}
}
ptoken=getpid();
printf("Pid padre(P0): %d",ptoken);
signal(SIGUSR1,Gestione);
close (matfd[0][0]); write(matfd[0][1],&ptoken,sizeof(int));
pause();
return 0;
}
Pare funzioni, ma siccome ho l'esame tra breve, vorrei un vostro parere
e qualche consiglio.
Forse come codice è un pochino troppo "sporco" credo...
Ci sarebbe un' alternativa usando exec: separando il codice del padre da
quello del generico figlio, e passando la "i" del for come stringa alla
exec, per poi riconvertirla in numero nel figlio usando una cosa come:
int i; sscanf(argv[1],"%d",&i), cosi' potrei gestire le pipe "i" e
"i+1" del generico figlio, ma non ci ho neanche provato, temo
impazzirei!!! :-)
Si progetti in ambiente Unix/C la seguente interazione di processi:
- il sistema consiste di N+1 processi che interagiscono a due a due
tramite una delle N pipe disponibili: la pipe p_i è utilizzata in lettura
dal processo P_i e in scrittura dal processo P_i-1 ;
- il processo P_0 inoltra il proprio pid nella pipe e attende l'arrivo di un
segnale;
- ogni processo P_i (con i<N) preleva il messaggio dalla pipe p_i e lo
scrive nella pipe p_i+1 ;
- il processo P_N, ricevuto il pid di P_0, provvede ad inviargli un
segnale SIGUSR1.
Consigli del docente del corso:
1)Abbiamo un processo padre e N suoi processi figli
2)La struttura dati che deve contenere le pipe deve essere una matrice
di N righe e due colonne.
Questo il mio tentativo:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#define N 10
void Gestione(int s){
printf("Segnale ricevuto\n");
}
int main()
{
int i,pid,ptoken;
int matfd[N][2];
for(i=0;i<N;i++)
pipe(matfd[i]); //creo le N pipe su cui far passare il pid del padre
for(i=0;i<N;i++){
pid=fork();
if(pid==-1) {perror("Errore fork\n"); _exit(1);}
if (pid==0) {
printf("Processo P%d\t",i+1); close(matfd[i][1]); close(matfd[i+1][0]);
//chiudo i "lati" delle pipe su cui non devo leggere/scrivere
read(matfd[i][0],&ptoken,sizeof(int)); printf("Ptoken: %d\n",ptoken);
if (i==(N-1)) {kill(ptoken,SIGUSR1); _exit(0);} //ossia sono l'ultimo
processo figlio e mando il segnale al padre
else {write(matfd[i+1][1],&ptoken,sizeof(int)); _exit (0);}
}
}
ptoken=getpid();
printf("Pid padre(P0): %d",ptoken);
signal(SIGUSR1,Gestione);
close (matfd[0][0]); write(matfd[0][1],&ptoken,sizeof(int));
pause();
return 0;
}
Pare funzioni, ma siccome ho l'esame tra breve, vorrei un vostro parere
e qualche consiglio.
Forse come codice è un pochino troppo "sporco" credo...
Ci sarebbe un' alternativa usando exec: separando il codice del padre da
quello del generico figlio, e passando la "i" del for come stringa alla
exec, per poi riconvertirla in numero nel figlio usando una cosa come:
int i; sscanf(argv[1],"%d",&i), cosi' potrei gestire le pipe "i" e
"i+1" del generico figlio, ma non ci ho neanche provato, temo
impazzirei!!! :-)