tags:

views:

217

answers:

3

I would like to implement a bidirectional fifo. The code below is functioning but it is not using bidirectional fifo. I have searched all over the internet, but haven't found any good example...

How can I do that?

Thanks,

WRITER.c:

#include <stdio.h>

#include <unistd.h>

#include <string.h>

#include <sys/types.h>

#include <sys/wait.h>
#include <fcntl.h>



#define MAXLINE 4096

#define READ 0

#define WRITE 1


int main (int argc, char** argv)
{
 int a, b, fd;

 do {
   fd=open("/tmp/myfifo",O_WRONLY);
   if (fd==-1) sleep(1);
  } while (fd==-1);

  while (1) {
   scanf("%d", &a);
   scanf("%d", &b);

   write(fd,&a,sizeof(int));
   write(fd,&b,sizeof(int));

   if (a == 0 && b == 0)
   {
    break;
   }

  }

  close(fd);
  return 0;
}

READER.c:

#include <stdio.h>

#include <unistd.h>

#include <string.h>

#include <sys/types.h>

#include <sys/wait.h>
#include <fcntl.h>
#include <sys/stat.h>




#define MAXLINE 4096

#define READ 0

#define WRITE 1



int main(void)

{
  int n1, n2;
  int fd;

  mkfifo("/tmp/myfifo",0660);
  fd=open("/tmp/myfifo",O_RDONLY);

  while(read(fd, &n1, sizeof(int) ))
  {
 read(fd, &n2, sizeof(int));

 if (n1 == 0 && n2 == 0)
 {
  break;
 }

 printf("soma: %d\n",n1+n2);

  printf("diferenca: %d\n", n1-n2);

   printf("divisao: %f\n", n1/(double)n2);

   printf("multiplicacao: %d\n", n1*n2); 
  }

  close(fd);

  return 0;
}
+5  A: 

FIFOs tend to be one way. If you want a FIFO you can both read from and write to, chances are what you really want is either a pair of FIFOs (one in each direction) or a UNIX socket.

cHao
A: 

FIFOs (also known as named pipe) provide a unidirectional interprocess communication channel. A FIFO has a read end and a write end. Data written to the write end of a FIFO can be read from the read end of the FIFO. Because they are unidirectional, a pair of FIFOs is required for bi-directional communication.

As cHao suggested, another option would be to use a Unix socket. Unix domain sockets take a bit more overhead to setup (socket creation, initialization and connection) than a FIFO, but are more flexible and offer bidirectional communication.

jschmier
A: 

Another option is to use a psudo-terminal (ptty). You can also use TCP sockets, which have higher overhead than UNIX sockets, but would work.

Bidirectional pipes are often discouraged because of the possibility of deadlock (prog1 is waiting on data from prog2 which is waiting on data from prog1 which is waiting on data from prog2 ...), but this can occur with any of the workarounds as well, and can occur with commonly used protocols like SMTP (simple mail transport protocol) as each side plays a role in a conversation.

If you think that a deadlock could occur you may want to make at least one side has a timeout, which you can do by one of the poll functions (including poll, select, pselect, and epoll_*) or by arranging for an SIGALM to be delivered (with alarm or a few other functions which allow for shorter times and more control) so that your program can get kicked out of deadlock.

nategoose