Мое приложение имеет две темы. Каждый поток получает некоторые данные с сервера через каждый сокет. Потоки ждут возврата epoll_wait (). Иногда epoll_wait () возвращает -1, а errno — EINTR. EINTR означает, что системный вызов () прерывается сигналом. Я добавил в процесс EINTR.
Однако я не знаю, какой сигнал поступил и почему поступил сигнал. Интересно.
Я создал тему.
sigset_t sMaskOfSignal;
sigset_t sOldMaskOfSignal;
sigfillset(&sMaskOfSignal);
sigprocmask(SIG_UNBLOCK, &sMaskOfSignal, &sOldMaskOfSignal)
while(1)
{
sigwait(&sMaskOfSignal, &sArrivedSignal);
fprintf(stdout, "%d(%s) signal caught\n", sArrivedSignal, strsignal(sArrivedSignal));
}
Я не смог поймать сигнал, когда epoll_wait () прерывается.
Когда я выполняю свое приложение в инструменте strace, epoll_wait () никогда не прерывается.
Моя проблема очень хорошо воспроизводится в инструменте GDB. Мне нужна помощь ….
Вы можете попробовать реализовать свой собственный обработчик сигналов. Если ваше приложение снова прервано сигналом, будет вызван ваш собственный обработчик сигнала, и вы увидите, какой сигнал был подан.
void
signal_callback_handler(int signum)
{
printf("Caught signal %d\n",signum);
exit(signum); // terminate application
}
int main()
{
// Register signal handler for all signals you want to handle
signal(SIGINT, signal_callback_handler);
signal(SIGABRT, signal_callback_handler);
signal(SIGSEGV, signal_callback_handler);
// .. and even more, if you want to
}
Не очень удобный метод, но он (надеюсь) позволит вам выяснить, какой сигнал был поднят. Посмотрите здесь чтобы увидеть различные сигналы, которые могут быть обработаны (примечание: не все сигналы могут быть обработаны в вашем собственном обработчике сигналов (!)).
Может быть, вам следует попробовать установить обработчик сигналов для перехвата всех сигналов и установить флаги сигналов на SA_SIGINFO
что-то вроде этого
struct sigaction act;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO;
act.sa_sigaction = <handler>;
sigaction(SIGFPE, &act, 0);
sigaction(SIGHUP, &act, 0);
sigaction(SIGABRT, &act, 0);
sigaction(SIGILL, &act, 0);
sigaction(SIGALRM, &act, 0);
sigaction(SIGALRM, &act, 0);
.
.
.
//and your handler looks like
void handle_sig (int sig, siginfo_t *info, void *ptr)
{
printf ("Signal is %d\n",sig);
}
Зарегистрируйте обработчик в вашей основной программе и игнорируйте EINTR в epoll.