Problema della Sincronizzazione di Processi in UNIX
Si generi un codice C per linux che generi due processi, uno che esegua il comando ls > lista.txt che genera il file lista.txt e aspetti la terminazione del secondo processo , ed un secondo che aspetti che il primo processo generi il file e lo visualizzi sull’output.
#include <stdio.h>/* printf(), puts(), fprintf(), stderr */
#include <unistd.h>/* fork(), execlp(), pid_t */
#include <errno.h>/* errno */
#include <sys/wait.h>/* waitpid(), WEXITSTATUS() */
#include<signal.h>
FILE *f; // puntatore al file
int pidpadre; // pid del padre
int main(void);
int child(void); // figlio
int parent(int pid); // padre
void announce();
int main(void){
signal(SIGALRM,announce); // creo il segnale di tipo SIGALRM e associato a announce
int pid;
puts("Il parent eseguira': ls > lista.txt. Il figlio aspetta il risultato e visualizza lista.txt. Il padre aspetta la visualizzazione, aspetta che muoia il figlio e muore!");
switch(pid = fork()) {
case 0:
sleep(1);
child();
case -1:
fprintf(stderr,"Anche se non capisco perchè: Errore %d in fork().\n",errno);
_exit(errno);
default:
parent(pid);
}
return 0;
}
int parent(int pid){
int status; // status del figlio (uscita)
printf("Sono il padre, ho il pid: %d. Sto eseguendo il comando!\n",getpid());
// Personalmente avrei voluto evitare di utilizzare la chiamata system, ma exec non funziona con il carattere >!!!
if(system("/bin/ls > lista.txt") == -1) { // eseguo il comando
fprintf(stderr,"Errore %d in system().\n",errno);
_exit(errno);
}
printf("Sono il padre, ho il pid: %d. Ho generato il file e sto inviando l'allarme!\n",getpid());
alarm(1);
printf("Sono il padre, ho il pid: %d. Ho inviato l'allarme! Aspetto che il figlio printi il file e esca\n",getpid());
pause();
if(waitpid(pid,&status,0) <= 0) { // aspetto che termini il figlio
printf("Errore %d in waitpid().\n");
_exit(errno);
}
printf("Sono il padre, ho il pid: %d. Il figlio e' morto con stautus: %d, mi uccido!\n",getpid(), status);
return 0;
}
int child(){
printf("Sono il figlio, ho il pid: %d. Sto aspettando che papa' generi il file!\n",getpid());
sigwait(SIGALRM,NULL);
printf("Sono il figlio, ho il pid: %d. Papa' ha generato il file, lo printo!\n",getpid());
if(system("cat lista.txt") == -1) { // eseguo il comando
fprintf(stderr,"Errore %d in system().\n",errno);
_exit(errno);
}
printf("Sono il figlio, ho il pid: %d. Ho printato il file, informo papa' che l'ho fatto!\n",getpid());
alarm(1);
printf("Sono il figlio, ho il pid: %d. Ho detto a papa' quello che ho fatto...mi ammazzo!\n",getpid());
return 0;
}
void announce() // funzione di stampa!
{ fprintf(stdout,"Sveglia! \n");
//_exit (0);
}
VERSIONE ALTERNATIVA -
GaS
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
int main(){
int status, i;
pid_t pid;
if( (pid = fork()) == 0)
{
printf("Sono il figlio e mi devo occupare della scrittura su file\n");
if(system("/bin/ls > lista.txt") == -1)
{
fprintf(stderr,"Errore %d in system().\n",errno);
_exit(errno);
}
sleep(1); // superfluo... giusto per farlo durare di piu'
printf("Scrittura file completata!\n");
exit(7); // e' un bel numero dopo tutto!
}
else
{
printf("Sono il padre e devo fare il cat.. attendo mio figlio\n");
while ( (pid = waitpid(-1, &status, 0)) > 0 )
{
if (WIFEXITED(status)) /* ritorna 1 se il figlio ha terminato correttamente */
{
printf("Il figlio ha terminato con con exit status=%d\n", WEXITSTATUS(status));
if(system("/bin/cat lista.txt") == -1) // eseguo il comando
{
fprintf(stderr,"Errore %d in system().\n",errno);
_exit(errno);
}
}
else
printf("Il figlio non ha terminato correttamente\n");
}
}
exit(0);
}
Torna a Lab Sistemi Operativi
There are 2 comments on this page. [Visualizza commenti]