Reputation: 217
I'm having a difficult time figuring out how select() is suppose to work with pipes in UNIX. I've scanned the man pages several times, and I don't completely understand the given definition.
From reading the man pages, I was under the impression that select() would make the system wait until one of the file descriptors given could make a read (in my case) from a pipe without blocking.
Here's some of my outline code[EDITED]:
int size, size2;
fd_set rfds;
struct timeval tv;
char buffer[100];
char buffer2[100];
int retval;
while(1)
{
FD_ZERO(&rfds);
FD_SET(fd[0], &rfds);
FD_SET(fd2[0], &rfds);
tv.tv_sec = 2;
tv.tv_usec = 0;
retval = select(2, &rfds, NULL, NULL, &tv); //2 seconds before timeout
if(retval == -1)
perror("Select failed.\n");
else if(retval)
{
size = read(fd[0], buffer, sizeof(buffer));
if(size > 0)
printf("Parent received from even: %s\n", buffer);
size2 = read(fd2[READ], buffer2, sizeof(buffer2));
if(size2 > 0)
printf("Parent received from odd: %s\n", buffer2);
}
else
printf("No data written to pipe in 2 last seconds.\n");
}
I have two pipes here. Two children processes are writing to their respective pipes and the parent has to read them both in.
As a test, I write a small string to each pipe. I then attempt to read them in and prevent blocking with select. The only thing that gets printed out is the string from the even pipe. It appears to still be blocking. I am becoming frustrated as I feel like I'm missing something on the man pages. Could someone tell me what I'm doing wrong?
Upvotes: 2
Views: 4763
Reputation: 5637
After select()
returns, 0 or more of your file descriptors will be in a "ready" state where you can read them without blocking. But if you read one that's not ready, it will still block. Right now you are reading all of them, and since select() only waits until one is ready, it's very likely that another will not be.
What you need to do is figure out which ones are ready, and only read()
from them. The return value of select()
will tell you how many are ready, and you can ask if a specific one is ready with the ISSET()
macro.
Upvotes: 5