[C, Linux] Pipe e funzioni bloccanti che... non bloccano. [RISOLTO]

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
Avatar utente
Blallo
Packager
Packager
Messaggi: 3302
Iscritto il: ven 12 ott 2007, 11:37
Nome Cognome: Savino Liguori
Slackware: 14.2 / 12.2
Kernel: 4.4.14-smp
Desktop: DWM
Località: Torino / Torremaggiore (FG)
Contatta:

[C, Linux] Pipe e funzioni bloccanti che... non bloccano. [RISOLTO]

Messaggio da Blallo »

Ho un programma del genere, deve prendere una stringa da un figlio produttore e mandarla via pipe ad un figlio consumatore che la trasforma in maiuscolo:

Codice: Seleziona tutto

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/wait.h>

static void consumer (int *pipeIN, int *pipeOUT);
static void producer (int *pipeIN, int *pipeOUT);

int main () {

	pid_t pidProd, pidCons;
	int fd1[2], fd2[2];

	if (signal (SIGUSR1, signalHandler) == SIG_ERR) {
		fprintf (stderr, "Signal Handler Error.\n");
		return 1;
	}

	fflush (stdout);

	pidCons = fork ();
	pipe (fd1);
	pipe (fd2);
	fflush (stdin);
	fflush (stdout);

	if (pidCons == 0) {
		consumer (fd1, fd2);
	} else {
		pidProd = fork ();

		if (pidProd == 0) {
			producer (fd2, fd1);
		}
	}

	wait ((int *) 0);
	wait ((int *) 0);

	remove (TMPFILE);

	return EXIT_SUCCESS;
}

static void producer (int *pipeIN, int *pipeOUT) {
	
	char buffer[1024];
	int flag;

	flag = 1;
	close (pipeIN[1]);
	close (pipeOUT[0]);

	while (flag) {
		fprintf (stdout, "Producer: ");
		fflush (stdout);
		scanf ("%s", buffer);
		write (pipeOUT[1], buffer, strlen (buffer)+1);
		read (pipeIN[0], &flag, sizeof (int));
	}
	close (pipeIN[0]);
	exit (0);
}

static void consumer (int *pipeIN, int *pipeOUT) {
	
	char buffer[1024];
	int flag, i;

	flag = 1;
	close (pipeIN[1]);
	close (pipeOUT[0]);

	read (pipeIN[0], buffer, 1024);
	while (flag) {

		if (strcmp (buffer, "end") == 0) {
			flag = 0;
			close (pipeIN[0]);
		} else {
			for (i = 0; i < strlen (buffer); i++) {
				buffer[i] = toupper (buffer[i]);
			}
			fprintf (stdout, "Consumer: %s\n", buffer);
			fflush (stdout);
		}
		write (pipeOUT[1], &flag, sizeof (int));
		read (pipeIN[0], buffer, 1024);
	}
	exit (0);
}
Mi aspettavo che la "read" bloccasse, ma come output ottengo:

Codice: Seleziona tutto

Consumer: T
Producer: 
che non ha molto senso.
E ovviamente non funziona.
Mi sapete dare una mano?
Ultima modifica di Blallo il lun 19 set 2016, 17:07, modificato 1 volta in totale.

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6628
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: [C, Linux] Pipe e funzioni bloccanti che... non bloccano.

Messaggio da targzeta »

Le pipe vanno create prima della fork altrimenti il consumer e il main avranno pipe diverse.

Non ho capito però l'uso di tutte quelle flush.

Emanuele

P.S. Quando si invocano le funzioni, non ci dovrebbe essere spazio tra il nome e le parentesi. Così come nelle definizioni o dichiarazioni, nessuno spazio tra nome e parentesi. Guarda un po' di coding style
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
Blallo
Packager
Packager
Messaggi: 3302
Iscritto il: ven 12 ott 2007, 11:37
Nome Cognome: Savino Liguori
Slackware: 14.2 / 12.2
Kernel: 4.4.14-smp
Desktop: DWM
Località: Torino / Torremaggiore (FG)
Contatta:

Re: [C, Linux] Pipe e funzioni bloccanti che... non bloccano.

Messaggio da Blallo »

targzeta ha scritto:Le pipe vanno create prima della fork altrimenti il consumer e il main avranno pipe diverse.

Non ho capito però l'uso di tutte quelle flush.

Emanuele

P.S. Quando si invocano le funzioni, non ci dovrebbe essere spazio tra il nome e le parentesi. Così come nelle definizioni o dichiarazioni, nessuno spazio tra nome e parentesi. Guarda un po' di coding style
Grazie mille per entrambe le info!

Rispondi