Двунаправленный FIFO - PullRequest
       17

Двунаправленный FIFO

2 голосов
/ 27 апреля 2010

Я хотел бы реализовать двунаправленный fifo. Код ниже работает, но он не использует двунаправленный fifo. Я искал по всему Интернету, но не нашел хорошего примера ...

Как я могу это сделать?

Спасибо

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;
}

Ответы [ 3 ]

10 голосов
/ 27 апреля 2010

FIFO имеют тенденцию быть односторонними. Если вам нужен FIFO, из которого вы можете как читать, так и записывать, скорее всего, вам действительно нужна пара FIFO (по одному в каждом направлении) или сокет UNIX.

3 голосов
/ 27 апреля 2010

FIFO (также называемые именованными каналами) обеспечивают однонаправленный межпроцессный канал связи. FIFO имеет конец чтения и конец записи. Данные, записанные в конец записи FIFO, могут быть прочитаны из конца чтения FIFO. Поскольку они однонаправлены, для двунаправленной связи требуется пара FIFO.

Как и cHao предложил , другой вариант будет использовать сокет Unix. Доменные сокеты Unix требуют немного больше времени на установку (создание сокетов, инициализацию и подключение), чем FIFO, но более гибки и обеспечивают двунаправленную связь.

0 голосов
/ 27 апреля 2010

Другой вариант - использовать псевдо-терминал (ptty). Вы также можете использовать сокеты TCP, которые имеют более высокие издержки, чем сокеты UNIX, но будут работать.

Двунаправленные каналы часто не рекомендуется из-за возможности тупика (prog1 ожидает данные от prog2, ожидающие данные от prog1, ожидающие данные от prog2 ...), но это может произойти с любым из обходных путей и может происходить с обычно используемыми протоколами, такими как SMTP (простой почтовый транспортный протокол), поскольку каждая сторона играет роль в разговоре.

Если вы считаете, что может произойти взаимоблокировка, вы можете сделать так, чтобы хотя бы у одной стороны был тайм-аут, что вы можете сделать с помощью одной из функций опроса (включая poll, select, pselect и epoll_ *) или организовав SIGALM, который должен быть доставлен (с сигнализацией или несколькими другими функциями, которые обеспечивают более короткое время и больший контроль), так что ваша программа может выйти из тупика.

...