Hello everybody
I have run into a bit of trouble with my use of the select() function on some file descriptors generated with the sockpair() function.
Basically, I would like for the main process to have a number of sons, each of which will communicate with the former through a pair of sockets. Since I believe that some sons will take more time to generate their output, I would like for the father to gather that output asynchronously, meaning that he will first recieve data from the first son that finishes. I have simulated this artificially by making some sons have a time-consuming loop, but the problem is that the other sons all send their output correctly, whereas the sons that take a while to process end up not "becoming set" in the fd_set which corresponds to the select(), and the father never recieves their output (despite the fact that their write() function seems to have no problem writing to.. something).
I hope I've been able to describe the problem accurately:
Code:
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<errno.h>
#include <netinet/in.h>
#define MAX_FII 16
extern int errno;
int main(int argc, char * argv[])
{
int socketi[MAX_FII][2], status;
fd_set readfds,actfds;
struct timeval tv;
int ndfs;
for(int i=0;i<10;++i)
{
if(socketpair(AF_UNIX,SOCK_STREAM,0,socketi[i])<0)
{
printf("eroare %d la socketpair!\n",errno);
}
status = fork();
if(status)
{
//wait(NULL);
}
else
{
close(socketi[i][1]);
char msg[20];
bzero(msg,sizeof(msg));
sprintf(msg,"%d",i);
if(i%2){ //this is the artificial loop, basically all the "odd" sons wil stall a bit
for(int j=0;j<37500;++j)
for(int k=0;k<15000;++k);
qDebug("We shall write %d !!",i);
}
int car;
if((car=write(socketi[i][0],msg,sizeof(msg)))<0)
{
printf("eroare %d la write!\n",errno);
}
else
{
// if(i==1)
// printf("%d ",car);
}
close(socketi[i][0]);
qDebug(" %d",car); // for all 10 sons the value of the number of characters written is 20
exit(1);
}
}
FD_ZERO(&readfds);
ndfs=0;
tv.tv_sec=2;
tv.tv_usec=0;
for(int i=0;i<10;++i)
{
close(socketi[i][0]);
ndfs = (ndfs<socketi[i][1])?socketi[i][1]:ndfs;
FD_SET(socketi[i][1],&readfds);
}
int counter = 0;
while(counter<10)
{
int nrselect;
if((nrselect=select(ndfs+1,&readfds,NULL,NULL,&tv)) < 0)
{
printf("eroare %d la select\n",errno);
}
for(int i=0;i<10;++i)
{
if(FD_ISSET(socketi[i][1],&readfds))
{
char msg[512];
bzero(msg,sizeof(msg));
if(read(socketi[i][1],msg,512)<0)
{
printf("eroare %d la read! \n",errno);
}
qDebug("%s !",msg);
++counter;
close(socketi[i][1]);
FD_CLR(socketi[i][1],&readfds);
qDebug("%d ",readfds);
}
}
}
return 0;//app.exec();
}
I'm working under Linux, using the QT framework. the output produced is:
Code:
0 !
2 !
4 !
6 !
8 !
We shall write 5 !!
We shall write 9 !!
We shall write 1 !!
We shall write 3 !!
We shall write 7 !!
<<here the program stalls indefinitely>>
which means that 0,2,4,6,8 got received correctly, and 5,9,1,3,7 never got read()
I would appreciate any help. Thank you.