Я пишу программу C на Linux, где у меня есть основной() и два созданных им pthreads. В одном из pthreads у меня есть вызов функции accept().Функция блокировки accept() перезапускается, когда SIGINT происходит, даже если флаг SA_RESTART установлен на ноль
У меня есть обработчик сигнала, который вызывается при получении SIGINT, SIGQUIT или SIGTERM.
Я ожидаю, потому что я делаю флаг SA_RESTART ноль, когда я нажимаю ctrl-c, функция accept() возвращает EINTR вместо перезапуска, однако я понял через связку вызовов printf во время отладки (чтобы увидеть, какие строки выполняются путем печати, где находится код), что хотя мое приложение может захватить SIGINT, функция accept остается заблокированной, она не прерывается с EINTR и не переходит к следующей строке кода. Вот мои настройки внутри основной()
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");
}
Вот потоковой, где принимают() вызов делается (я пытался удалить несвязанный материал, чтобы сделать мой вопрос более понятен):
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);
}
}
Надеюсь, я ясно дал понять.
Итак, теперь я задаюсь вопросом, что отсутствует или неверно, поскольку я не могу увидеть поведение, описанное в руководствах linux для SA_RESTART.
Это 'if (fcntl (server_socket_fd, F_SETFL, 0) ...' выглядит странно, чтобы не сказать неправильно. – alk
@alk Я пытался сделать файловый дескриптор блокирующим таким образом, поскольку по умолчанию это не так. Я открыт для предложений :) – etugcey
О том, как переключиться в состояние блокировки сокета с помощью 'fcntl()', возможно, вам понравился этот ответ: http://stackoverflow.com/a/1549344/694576 – alk