【发布时间】:2016-08-07 07:06:16
【问题描述】:
我正在 Linux 上编写一个 C 程序,其中我有一个 main() 和两个由它创建的 pthread。在其中一个 pthread 中,我调用了 accept() 函数。
我有一个在收到 SIGINT、SIGQUIT 或 SIGTERM 时调用的信号处理程序。
我的期望是,因为我将 SA_RESTART 标志设为零,所以当我按下 ctrl-c 时,accept() 函数应该返回 EINTR 而不是重新启动,但是我在调试时通过一堆 printf 调用实现了(查看哪些行是通过打印代码所在的位置执行),即使我的应用程序能够捕获 SIGINT,accept 函数仍然被阻止,它不会因 EINTR 而失败并且不会移动到下一行代码。 这是我在 main() 中的设置
struct sigaction signal_action;
signal_action.sa_flags = 0; // Don't restart the blocking call after it failed with EINTR
signal_action.sa_handler = terminate;
sigemptyset(&signal_action.sa_mask);
sigfillset(&signal_action.sa_mask); // Block every signal during the handler is executing
if (sigaction(SIGINT, &signal_action, NULL) < 0) {
perror("error handling SIGINT");
}
if (sigaction(SIGTERM, &signal_action, NULL) < 0) {
perror("error handling SIGTERM");
}
if (sigaction(SIGQUIT, &signal_action, NULL) < 0) {
perror("error handling SIGQUIT");
}
这是信号处理程序:
void terminate (int signum)
{
terminate_program = 1;
printf("Terminating.\n");
}
这是进行 accept() 调用的 pthread(我试图删除不相关的内容以使我的问题更容易理解):
void* pthread_timerless_socket_tasks(void* parameter)
{
server_socket_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(server_socket_fd < 0)
{
perror("error creating IPv4 TCP stream socket");
return (NULL);
}
printf("socket created\n"); // for debugging
if(fcntl(server_socket_fd, F_SETFL, 0) < 0)
{
perror("error making socket_fd blocking");
close(server_socket_fd);
return (NULL);
}
while(!terminate_program)
{
printf("socket blocking on accept\n"); // for debugging
client_socket_fd = accept(server_socket_fd,(struct sockaddr *) &client_address, &client_length);
printf("socket accepted?\n"); // for debugging
if(client_socket_fd < 0)
{
perror("error accepting socket_fd");
close(server_socket_fd);
return (NULL);
}
}
我希望我说清楚了。
所以,现在我想知道缺少什么或不正确,因为我看不到 SA_RESTART 的 linux 手册中描述的行为。
【问题讨论】:
-
这个
if(fcntl(server_socket_fd, F_SETFL, 0) ...看起来很奇怪,不要说错。 -
@alk 我试图让文件描述符以这种方式阻塞,因为默认情况下它不是。我愿意接受建议:)
-
关于如何使用
fcntl()切换到套接字的阻塞状态,您可能希望看到这个答案:stackoverflow.com/a/1549344/694576
标签: c linux pthreads signals blocking