我正在实现一个经典的 map-reduce 程序,其中我有一个父级,它生成 N 个子级(maps)+ 1 个(reduce)。父级通过未命名的管道向 N 个子级中的每一个发送信息。映射处理请求并发送结果,一个 int,以减少。reduce 进行选择并总结从 map 到 reduce 的管道上写入的每个计数器。
最后,reduce 必须发送带有结果的信号 SIGUSR1,但我的代码多次执行此操作并且错误,因为它始终在信号处理程序中打印 o。是代码的一部分:
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");
}
}
在父级中,在创建管道和子级之后,我有这样的东西:
(...)
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);
}
问题是reduce进程正确求和并正确打印,但是信号被发送了很多次,我只想要一个,即在wend向父级发送信号sigusr1,在pause()中被阻塞,然后打印全局 var 结果。
我怎样才能做到这一点?reduce有什么问题不是吗?