我有2个FIFO的问题,每个FIFO都有读写功能

时间:2010-06-20 11:48:36

标签: c stream fifo

附加的代码应允许2个终端之间的通信。通过2个FIFO进行通信,这些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;   

}

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

你这里有一团糟。

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

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

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