【发布时间】:2020-03-05 14:46:25
【问题描述】:
我正在尝试处理来自不同进程的套接字连接,同时异步处理来自alarm 函数的 SIGALRM。为了模拟和测试这一点,我使用了 Linux 命令nc 127.0.0.1 [port] 和kill -14 $(myprocess)。但是,当运行kill 命令后跟nc 命令时,select 会立即以类似方式的无限循环返回。包含select 语句的C 代码如下。
int main() {
int port = 4555;
int master_sockfd;
bind_and_listen(&master_sockfd, port);
signal(SIGALRM, handle_alarm);
for (;;) {
fd_set readfds;
int max_fd = master_sockfd;
FD_ZERO(&readfds);
FD_SET(master_sockfd, &readfds);
printf("waiting for master_sockfd to be set\n");
int activity = select(max_fd + 1, &readfds, NULL, NULL, NULL);
if ((activity < 0) && (errno != EINTR)) {
perror("select() ");
exit(EXIT_FAILURE);
} else if (errno == EINTR) {
perror("select() ");
if (FD_ISSET(master_sockfd, &readfds)) {
printf("Why is sockfd ready for I/O if select was interrupted with a signal?\n");
}
continue;
} else if (FD_ISSET(master_sockfd, &readfds)) {
printf("Reading from socket\n");
// handle client
}
}
return 0;
}
void handle_alarm() {
printf("handling alarm\n");
}
然后,在执行kill -14 $(myprocess); nc 127.0.0.1 4555
输出如下:
select() : Interrupted system call
Why is sockfd ready for I/O if select was interrupted with a signal?
waiting for master_sockfd to be set
select() : Interrupted system call
Why is sockfd ready for I/O if select was interrupted with a signal?
waiting for master_sockfd to be set
select() : Interrupted system call
Why is sockfd ready for I/O if select was interrupted with a signal?
waiting for master_sockfd to be set
.
.
.
无限打印。
为什么会这样?
【问题讨论】: