【问题标题】:I Have a problem with 2 FIFO for read and write in each我有 2 个 FIFO 的读写问题
【发布时间】:2011-03-05 23:30:48
【问题描述】:

附加的代码应该允许两个终端之间的通信。通过在当前目录中创建的 2 个 FIFO 进行通信。程序必须打开 2 个 fifo,儿子从 STDIN 读取并放入 fifo1,父亲从另一个 fifo 读取并在终端上打印。以这种方式进行通信,因为对程序的调用是:./myprog fifo1 fifo2(用于第一个终端)和 ./myprog fifo2 fifo1(用于第二个终端)。代码不好用,我怀疑子write()在fifo上执行的不好用。希望我解释清楚,帮助meeee :'(

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <poll.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>

int main(int argc,char* argv[])
{
    if(argc<3)
    {
        printf("Error: Too few arguments...\n");
        exit(-1);
    }

    char** buffer_in=(char**) malloc(sizeof(char*));
    char** buffer_out=(char**) malloc(sizeof(char*));
    size_t dim_buff=sizeof(char*);
    FILE* stream;
    FILE* input;
    int fifo_in, fifo_out, num_poll_c, num_poll_f, read_count, i,write_b;
    pid_t pid;
    ssize_t length;
    struct pollfd* fd_set_c=(struct pollfd*) malloc(sizeof(int));//for the child
    struct pollfd* fd_set_f=(struct pollfd*) malloc(sizeof(int));//for the father


    printf("Write character e press enter:\n");

    if((fifo_in=open(argv[1],O_RDWR|O_NONBLOCK))==-1)
        perror("error open");
    if((fifo_out=open(argv[2],O_RDWR|O_NONBLOCK))==-1)
        perror("error open");

    if((input=fdopen(STDIN_FILENO,"r"))==NULL)
        perror("error fdopen");


    if((pid=fork())==-1)
        perror("error fork");
    while(1)
    {   
        if(pid==0)  /*child*/   
        {   
            fd_set_c->fd=STDIN_FILENO;
            fd_set_c->events=POLLIN;
            if((num_poll_c=poll(fd_set_c, 1, -1))==-1)
                perror("error poll child");//poll on fifo_in
            if((length=getline(buffer_in,&dim_buff,input))==-1)
                perror("error getline");



                printf("The written word is::%s\n",*buffer_in);/*my control for see what in buffer_in is*/


            if((write_b=write(fifo_in,*buffer_in,dim_buff))==-1)
                perror("error write");

        }

        else    /*father*/
        {   
            fd_set_f->fd=fifo_out;
            fd_set_c->events=POLLIN;

            if((num_poll_f=poll(fd_set_f, 1, 5000))==-1)
                perror("error poll father");//poll on fifo_out      
            if((read_count=read(fifo_out,*buffer_out,SSIZE_MAX))==-1)
                perror("error read");//read on fifo_out
            for(i=0;i<=read_count;i++)
                printf("%s",buffer_out[i]);//print on stdout buffer_out


        }
    }
    return 0;   

}

【问题讨论】:

    标签: c stream fifo


    【解决方案1】:

    您应该使用管道(man 2 pipe. 或共享内存:man shmget)在您的进程之间进行通信,并使用信号量来保护读/写。在谷歌上寻找“生产者/消费者”。

    看看这个:http://users.evtek.fi/~tk/rtp/sem-producer-consumer.c 还有这个:http://knol.google.com/k/producer-consumer-problem#

    【讨论】:

    • Mmm...你的回答让我有点困惑:1-这不是普通管道而是命名管道(man 3 mkfifo)2-数据受poll保护(man 2 poll)3 - 我不认为我必须为 FIFO 创建共享内存!还是不行?
    【解决方案2】:

    你这里一团糟。

    父级可能会阻止 FIFO 中的read(),因为它仍然有打开的可写文件描述符。并且打开的可写文件描述符属于父进程本身。而且由于它在read() 中被阻止,因此无法写入。

    fork() 之后打开 FIFO。以更严格的模式打开:仅用于写入或仅用于读取,而不是通配符 O_RDWR。这样你就可以反映通常应用于 pipe()s 的逻辑。

    此外,在 STDIN_FILENO 上执行 poll() 是危险的,因为 stdio 是缓冲的。文件描述符可能没有可读取的内容 - 因为它之前已经全部读出,但位于 stdio 缓冲区内。如果你真的确定你知道你在做什么,至少尝试禁用缓冲,man setvbuf。但是在 fork() 存在的情况下我仍然不会这样做:缓冲数据可能会被读取两次:一次由子级读取,一次由父级读取。

    【讨论】:

      猜你喜欢
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-09
      • 1970-01-01
      • 2014-11-12
      相关资源
      最近更新 更多