HI,
I'm implementing a classical map-reduce program in which I have a parent that spwans N children(maps) + 1(reduce). The parent sends info, through unnamed pipes, to each one of the N children. The maps process the request and send the result, an int, to reduce. The reduce does a select and sums up every counter writen on the pipes from map to reduce.
At the end, reduce has to send a signal SIGUSR1 with the result, but my code does it many times and wrong, because it prints always o in the signal handler. Is part of the code:
void reduce() {
int answer;
int i = 0;
fd_set set;
FD_ZERO(&set); //clean set of pipes
while (1) {
for (i = 0; i < maps_nr; i++) {
FD_SET(fd_maps_to_reduce[i][READ], &set);
}
if (select(FD_SETSIZE, &set, NULL, NULL, NULL) > 0) {
printf("Entrou no select\n");
for (i = 0; i < maps_nr; i++) {
if (FD_ISSET(fd_maps_to_reduce[i][READ], &set)) {
close(fd_maps_to_reduce[i][WRITE]);
if (read(fd_maps_to_reduce[i][READ], &answer, sizeof (int))) {
result += answer;
printf("Result in reduce =%d\n", result);
} else {
printf("Reduce failed to read from pipe from son :%d!\n", i);
}
}
}
}//end of select
printf("Reduce is going to send a signal with result= %d!\n", result);
kill(getppid(), SIGUSR1);
printf("Already send!\n");
}
}
and in the parent, after creating pipes and children I have something like this:
(...)
signal(SIGUSR1, handle_signal);
while(exit){
(...)//this is a menu
for i->N
send a struct to each child (through write in respective pipe)
after the for do:
pause();//waiting for a signal to be caught
if (errno==EINTR)
printf("caught sigusr1");
}
void handle_signal(int signum) {
signal(SIGUSR1, handle_signal);
//print results
printf("Result: %d\n",result);
}
The problem is that the reduce process sums correctly and prints correctly, but the signal is being send many times and I only want one, i.e., in the wend sends a signal sigusr1 to the parent, which is blocked in pause(), and prints the global var result.
How can I do that? Is something wrong in reduce isn't it?