附加的代码应允许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;
}
答案 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()的情况下这样做:缓冲的数据可能会被读取两次:一次是子节点,一次是父节点。