Es cierto lo que vos decis, pero aun corrigiendo esos errores el
comportamiento extraño sigue pasando. Si al escritor le digo que mande
el \0 del final de las cadenas (en la linea: 'size_t count =
strlen(cadena);// + 1' descomento el + 1) me siguen llegando mal los
mensajes del otro lado.
Por ejemplo, si dejo todo como esta (con las correcciones indicadas
[1] ) y descomento el '// + 1' la salida que obtengo es:
7386: Mensaje numero 1 pid: 7387
7386: 7387
Si dejo comentado anda todo ok.
Lo extraño tambien es que si cambio el tamaño del buffer de lectura por
ejemplo poniendolo en 21, la salida que obtengo es
7467: Mensaje numero 1 pid
7467: : 7472
7467: ro 2 pid: 7472
7467: aje numero 3 pid: 74
7467: 72
alguna pista de que puede ser?
saludos
[1] el bloque de codigo que cambio con las correcciones queda:
const unsigned short count = 51; //tamaño del buffer de lectura
char buf[count];
memset(buf,0,count);
while ((leido = read(fd, buf,count-1)) > 0)
El mié, 22-10-2008 a las 08:34 -0300, juanii escribió:
> Hay dos problemas:
> El primero es que no inicializas el buffer del lector antes de la
> primer lectura del FIFO, por lo cual si el read trajera menos de 50
> bytes lo que queda en el resto del buffer es indefinido. El printf()
> va a imprimir el buffer hasta encontrar un \0. Si tuviste la suerte de
> que el destino pusiera un \0 en algun lugar del buffer, tendras el
> mensaje mas un poco de basura. Si no tuviste esa suerte, vas a estar
> accediendo a memoria ajena :)
> El segundo problema es parecido al otro pero mas sutil. Resulta que,
> bajo ciertas circunstancias la concurrencia te esta jugando en contra.
> El proceso escritor puede ser mucho mas rapido que el lector y
> escribir mas de 50 bytes en el FIFO antes que el lector lo lea por
> primera vez. Si se da ese caso (y se da) el primer read() llena el
> buffer con 50 bytes, pero como el buffer *es* de 50 bytes y estas de
> vuelta en el primer problema, no hay \0 final. La solucion mas facil
> es que pongas un buffer de 51 bytes y el ultimo lo dejes en \0
> siempre.
>
> Saludos!
>
> 2008/10/21 San Martín, Matías <[EMAIL PROTECTED]>:
> > buenas gente, a ver si alguno me puede ayudar con este problema.
> > La idea es que tengo un proceso lector y uno escritor que se comunican
> > mediante un FIFO. El proceso lector crea el FIFO y el escritor le manda 3
> > mensajes.Despues el escritor cierra su fd y cuando el lector obtiene un 0
> > como resultado del read cierra el suyo y elimina el FIFO.
> > El asunto es que el lector me recibie mal los mensajes si el escritor le
> > manda el \0 del final y no entiendo por que.
> > No se si ayuda pero,un dato curioso es qeu dependiendo de que tamaño tenga
> > el buffer de lectura (que determina en cuantas leidas recibo una cadena)
> > recibo distintos mensajes.
> > Si hago al escritor que no mande el \0 del final anda todo ok.
> > Alguien tiene alguna pista de porque puede ser este comportamiento??
> >
> > Les mando el codigo por si les sirve para algo:
> >
> > ________________________________
> >
> > #include <cstdio>
> > #include <cstdlib>
> > #include <cstring>
> > #include <sys/types.h>
> > #include <sys/stat.h>
> > #include <unistd.h>
> > #include <fcntl.h>
> > #include <errno.h>
> >
> > #define CANT_MAX_ESCRITORES 1//10
> > #define NOMBRE_FIFO "./miPipe"
> >
> > #include <sys/wait.h>
> >
> > using namespace std;
> >
> > int main(int argc, char **argv) {
> >
> > pid_t nuevoPid = 0;
> >
> > //se lanzan todos los procesos desde el mismo proceso padre
> > for (unsigned i = CANT_MAX_ESCRITORES; i-- && ((nuevoPid = fork()) > 0); );
> >
> > if (nuevoPid == -1){perror("No se pudo crear proceso\n");exit(1);}
> >
> > if (nuevoPid == 0)
> > {//proceso hijo, escritor
> >
> > int fd;
> > /* Si la tubería no existe cuando el proceso escritor intenta abrirla,
> > * el escritor vuelve a intentarlo cada segundo hasta que pueda abrirla */
> > while (((fd = open(NOMBRE_FIFO,O_WRONLY)) == -1) && (errno == ENOENT))
> > sleep(1);
> >
> > if (fd == -1){perror("No se pudo abrir el FIFO para escritura\n");exit(1);}
> >
> > //se escriben los 3 mensajes en el FIFO
> > const unsigned short tamBufCadena = 50;
> > char cadena[tamBufCadena];
> > for (unsigned short nmensaje = 1; nmensaje <= 3;nmensaje++)
> > {
> > memset(cadena,0,tamBufCadena);
> > sprintf( cadena, "Mensaje numero %d pid: %d\n", nmensaje, getpid() );
> > size_t count = strlen(cadena);// + 1; <============= ACA SI AGREGO EL +1 SE
> > COMPORTA DE LA FORMA "EXTRAÑA" DICHA
> > size_t escritoTotal;
> > ssize_t escrito;
> > escritoTotal = 0;
> >
> > while ((escritoTotal < count) && ((escrito = write(fd, ((char*)cadena) +
> > escritoTotal,count - escritoTotal)) > 0) )
> > escritoTotal += escrito;
> >
> > if (escrito == -1){perror("No se pudo escribir en el FIFO\n");exit(1);}
> > }
> >
> > if (close(fd) == -1){perror("No se pudo cerrar el FIFO de
> > escritura\n");exit(1);}
> >
> > exit(0);
> > }
> >
> > //proceso padre, lector
> >
> > //se crea el FIFO con permisos los permisos adecuados
> > if (mknod(NOMBRE_FIFO,S_IFIFO | 0666,0) == -1){perror("No se pudo crear el
> > FIFO\n");exit(1);}
> >
> > int fd;
> >
> > if ((fd = open(NOMBRE_FIFO,O_RDONLY)) == -1){perror("No se pudo abrir el
> > FIFO para lectura\n");exit(1);}
> >
> > ssize_t leido;
> > const unsigned short count = 50; //tamaño del buffer de lectura
> > char buf[count];
> >
> > //se lee del FIFO hasta que se cierra (devuelve 0) o hay error (devuelve -1)
> > while ((leido = read(fd, buf,count)) > 0)
> > {
> > printf("%d: %s\n",getpid(),buf);
> > memset(buf,0,count);
> > }
> >
> > if (leido == -1){perror("No se pudo leer del FIFO\n");exit(1);}
> >
> > if (close(fd) == -1){perror("No se pudo cerrar el FIFO de
> > lectura\n");exit(1);}
> > //se elimina el fifo
> > if (unlink(NOMBRE_FIFO) == -1){perror("No se pudo eliminar el
> > FIFO\n");exit(1);}
> > return 0;
> >
> > }
> >
> > ________________________________
> >
> > saludos, se agradece cualquier comentario,
> > _______________________________________________
> > Lista de correo Programacion.
> > [email protected]
> > http://listas.fi.uba.ar/mailman/listinfo/programacion
> >
> >
>
>
>
_______________________________________________
Lista de correo Programacion.
[email protected]
http://listas.fi.uba.ar/mailman/listinfo/programacion