[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.
Avatar utente
Blallo
Packager
Packager
Messaggi: 3292
Iscritto il: ven ott 12, 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]

Messaggioda Blallo » ven set 16, 2016 0:41

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 set 19, 2016 17:07, modificato 1 volta in totale.
My DWM configuration: https://github.com/8lall0/dwm

Feel free to use.

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

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

Messaggioda targzeta » ven set 16, 2016 22:08

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
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà 

Avatar utente
Blallo
Packager
Packager
Messaggi: 3292
Iscritto il: ven ott 12, 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.

Messaggioda Blallo » lun set 19, 2016 17:07

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!
My DWM configuration: https://github.com/8lall0/dwm

Feel free to use.