作为标题,我使用C在Linux系统中的两个程序之间完成这项工作。 但是,我遇到了一些问题。 假设我有一个服务器在十轮内将数据写入FIFO,并且 客户端将读取每一轮数据并写入另一个FIFO以进行馈送 回到服务器。 客户端将在每一轮中阻塞,直到服务器编写器数据进入。 但是,我的客户端程序无法执行此操作。
我使用fopen
打开FIFO,fgets
读取数据。
似乎没有阻止等待数据写入。
客户代码:
FILE *fp_R,*fp_W;
char temp[100];
fp_R = fopen(FIFO_R,"rb");
fp_W = fopen(FIFO_W,"wb");
for ( i = 0 ; i < 10 ; i ++ ) {
fgets(temp, 100, fp_R);
Handle Data;
fprintf(fp_W,DATA);
}
我希望fgets
等待服务器写入数据,以便我可以处理每一轮
感谢任何人的帮助
答案 0 :(得分:1)
正如TonyB所说,fopen()
函数将返回文件指针FILE*
FILE *fp_R, *fp_W;
char temp[100];
fp_R = fopen(FIFO_R,"rb");
fp_W = fopen(FIFO_W,"wb");
for ( i = 0 ; i < 10 ; i ++ ) {
char* ret = fgets(temp, 100, fp_R);
while(ret == null)
{
Sleep(1);
}
Handle Data;
fprintf(fp_W,DATA);
}
答案 1 :(得分:1)
read(2)
将阻止,直到有可用数据,或写作方close(2)
为其开放FD。 (在这种情况下,你将得到EOF)。
在strace
下运行您的程序,以查看它所进行的系统调用。
e.g。
peter@tesla:/tmp$ mkfifo mypipe
peter@tesla:/tmp$ strace cat mypipe
execve("/bin/cat", ["cat", "mypipe"], [/* 69 vars */]) = 0
...
open("mypipe", O_RDONLY # blocks until a writer opens the fifo
... # after starting the writing side:
= 3
fstat(3, {st_mode=S_IFIFO|0664, st_size=0, ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = -1 ESPIPE (Illegal seek)
mmap(NULL, 139264, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f70d245c000 # cat allocates a buffer. This might be from C stdio, or more likely custom buffering in GNU cat
read(3, "lkjsalkfj\n", 131072) = 10
write(1, "lkjsalkfj\n", 10lkjsalkfj
) = 10
read(3, # blocked on a read system call
请注意我的shell在运行cat
之前打开了管道。
我本可以做到的
strace tee /tmp/mypipe > /dev/null
$ strace cat > /tmp/mypipe
...
read(0, lkjsalkfj
"lkjsalkfj\n", 131072) = 10
write(1, "lkjsalkfj\n", 10) = 10
因此,添加sleep(3)
的建议是无稽之谈。您的代码看起来应该有效。你可能做错了其他事情,你应该使用strace
来查找它,因为这通常比在玩具程序中为系统调用添加错误检查更容易。 实际系统编程中的大多数代码都是检查系统调用的错误情况并处理它们。
如果您的读取没有阻止,我不会感到惊讶,因为他们会立即返回错误。
答案 2 :(得分:0)
添加1行并尝试如下:
int fp_R,fp_W;
char temp[100];
fp_R = fopen(FIFO_R,"rb");
fp_W = fopen(FIFO_W,"wb");
for ( i = 0 ; i < 10 ; i ++ ) {
sleep(1); or usleep(10);//try it fgets will wait for some time bcz of this
fgets(temp, 100, fp_R);
Handle Data;
fprintf(fp_W,DATA);
}