Newsgroup: it.comp.lang.c
Titolo: Produttore e Consumatore con i segnali.

Ciao a tutti, questo è il mio primo post.
Devo svolgere un progetto molto semplice, praticamente implementare il
problema del produttore consumatore usando come sincrronizzazione i
segnali.
Questo è il "main" del mio programma, purtroppo non riesco ad uscirne,
ringrazio qualsiasi aiuto
/*
	Producer-Consumer for the class `Laboratorio di Sistemi Operativi'
Univ. Venezia,
	aa 2007-2008, Prof. R. Focardi. This code is for didactic purposes
and can
	be modified and redistributed with no limitations.
	Descrizione: il processo principale crea un processo figlio il quale
svolgera' il ruolo diconsumatore.
	Viene utilizzato un file temporaneo "buffer_prod_cons" per
trasmettere i dati dal produttore al
	consumatore. I dati sono gli argomenti passati sulla linea di
comando.
	NOTA BENE: Per poter eseguire il programma e' necessario implementare
le 5 funzioni di
	sincronizzazione dichiarate qui sotto.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#define FINE "#END"	// simbolo per terminare la comunicazione
#define MAXLEN 128	// lunghezza massima dati
// primitive di sincronizzazione, da definire in un file esterno
 void attendi_produttore(pid_t pid);
 void attendi_consumatore(pid_t pid);
 void sveglia_produttore(pid_t pid);
 void sveglia_consumatore(pid_t pid);
 void attendi_init();
// stampa l'errore e termina (per comodita')
void die(char *s) {
	perror(s);
	exit(EXIT_FAILURE);
}
// scrive la stringa s sul file fd, azzerandolo preventivamente
void invia(int fd, char *s) {
	ftruncate(fd,0);  // sovrascrive
	lseek(fd,0,SEEK_SET); // azzera
	write(fd, s, strlen(s));
	fsync(fd); // flush
}
// legge la stringa s dal file fd
void ricevi(int fd, char *s) {
	int w=0;
	lseek(fd,0,SEEK_SET); // azzera
	// legge fino alla fine del file e al max MAXLEN caratteri
	w=read(fd,s,MAXLEN);
	s[w] = '\0'; // mette NULL alla fine della stringa
}
/*
	produci e consuma realizzano la produzione e consumazione dei dati.
	qui si possono inserire ritardi artificiali per simulare velocita'
	differenti.
	Ad esempio: un produttore piu' veloce sovrascrivera' dati mentre un
	consumatore piu' veloce ri-consumera' gli stessi dati.
*/
// La produzione non fa altro che stampare a video, restituire la
stringa s,
// piu' eventuali ritardi
char *produci(char *s) {
//	con la sleep "simulo" un produttore piu' o meno lento
 	sleep(1);
	printf("[Produttore ] produco %s\n",s);
	fflush(stdout);
	return s;
}
// La consumazione stampa a video e, eventualmente, introduce ritardi
void consuma(char *s) {
	printf("[Consumatore] consumo %s\n",s);
	fflush(stdout);
//	con la sleep "simulo" un consumatore piu o meno lento
	sleep(5);
}
main(int argc,char *argv [])
{
	int fd;
	pid_t pid;
        if (argc <= 1) {
                printf("[ERRORE] Inserire almeno un argomento\n");
                printf("USO: prod_cons dato1 dato2 ... datoN\n");
                exit(EXIT_FAILURE);
        }
	// crea il file buffer
	system("rm buffer_prod_cons");
	fd = open("buffer_prod_cons", O_RDWR | O_CREAT, 0644);
	// inizializza la sincronizzazione
	attendi_init();
	if ( (pid=fork()) < 0 )
		die("errore fork");
	else if ( pid == 0 ) { // figlio-consumatore
		char s[MAXLEN]="";
		while ( strcmp(s,FINE) != 0 ) {
			// attende che il produttore abbia prodotto
			attendi_produttore(getppid());
			// riceve il dato da consumare
			ricevi(fd, s);
			if ( strcmp(s,FINE) != 0 )
				// cosuma se c'e' qualcosa da consumare
				consuma(s);
			// avvisa chg il dato e' stato consumato
			sveglia_produttore(getppid());
		}
		printf("[%i] Consumatore (figlio) termina\n",getpid());
	} else { // padre-produttore
		int i=1;
		char *dato;
		// scrive, in sequenza, gli argv sul file fd
		while(argv[i] != NULL) {
			// produce: di fatto ritorna argv[i]
			dato=produci(argv[i]); i++;
			// invia il dato prodotto
			invia(fd, dato);
			// avvisa che il dato e' stato prodotto
			sveglia_consumatore(pid);
			// attende che il consumatore abbia consumato
			attendi_consumatore(pid);
		}
		invia(fd, FINE); // termina la trasmissione
		sveglia_consumatore(pid);
		printf("[%i] Produttore (padre) termina\n",getpid());
	}
}
void attendi_produttore(pid_t pid){
  printf("funzione attendi produttore %d\n",pid);
  pause();
  sleep(2);
}
void attendi_consumatore(pid_t pid){
 printf("funzione attendi consumatore 5d\n",pid);
 pause();
 sleep(2);
}
void sveglia_produttore(pid_t pid){
 printf("Funzione sveglia produttore%d\n",pid);
 sleep(2);
}
void sveglia_consumatore(pid_t pid){
 printf("Funzione sveglia consumatore%d\n",pid);
 sleep(2);
}
void attendi_init(){
 printf("Funzione attendi init\n");
 sleep(2);
}

 		while(argv[i] != NULL) {
Qui hai un problema di accesso alla memoria quando i > argc. 
Probabilmente comincia a leggere memoria sporca e non si ferma perche' 
non trova mai un valore di NULL (su altri sistemi si sarebbe piantato 
dandoti un errore di memory protection o simili...)
Prova a confrontare i con argc per uscire dal loop.
ciao
Giacomo