Reputation: 47
As title, I use C to do this job between two programs in Linux system. But, I encounter some problem. Assuming that I have a server write data to FIFO in ten rounds, and the client will read each round data and write another FIFO to feed back to server. The client will block in each round until that the server writer data in. However, my client program can't do this.
I use fopen
to open the FIFO and fgets
to read data.
It seems not to block to wait data write in.
client code:
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);
}
I want to fgets
to wait for server writing data in, so that I can handle each round
Thanks for anyone help
Upvotes: 3
Views: 2693
Reputation: 363999
read(2)
on a fifo will block until there's data available, or the writing side close(2)
es its open FD. (In which case you will get EOF).
Run your program under strace
, to see the system calls it makes.
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
note that my shell opened the pipe before running cat
.
I could have done
strace tee /tmp/mypipe > /dev/null
$ strace cat > /tmp/mypipe
...
read(0, lkjsalkfj
"lkjsalkfj\n", 131072) = 10
write(1, "lkjsalkfj\n", 10) = 10
So the suggestions to add a sleep(3)
are nonsense. Your code looks like it should work. You're probably doing something else wrong, and you should use strace
to find it, since that's often easier than adding error-checking to your system calls in toy programs. Most of the code in real systems programming is checking error conditions from system calls, and handling them.
I wouldn't be surprised if your reads aren't blocking because they're returning right away with an error.
Upvotes: 1
Reputation: 780
Add 1 line and try as below:
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);
}
Upvotes: 0
Reputation: 512
as TonyB said, the fopen()
function will return a file pointer 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);
}
Upvotes: 1