Смежный вопрос здесь и здесь .
В проекте Linux GPLv3 + https://github.com/bstarynk/helpcovid/ (многопоточный, C + +17, приложение веб-сервера) commit b616defc5e54ba869 . Необходима возможность изящного завершения такого веб-сервера (взаимодействующего с некоторой базой данных PostGreSQL с использованием libpqxx
). Итак, выпуск № 35 .
Я прочитал оба сигнала (7) и Сигнал-безопасность (7) и signalfd ( 2) . И я знаю о критике в отношении signalfd .
У меня есть один фоновый C ++ std::thread
poll (2) -ing для нескольких файловых дескрипторов. См. Файл hcv_background.cc
, где функция hcv_start_background_thread
вызывается из функции main
в файле hcv_main.cc
, а созданный std::thread
запускает функцию hcv_background_thread_body
(событие l oop делает опрос (2) ....)
Итак, hcv_start_background_thread
имеет:
{
sigset_t sigmaskbits;
memset (&sigmaskbits, 0, sizeof(sigmaskbits));
sigemptyset(&sigmaskbits);
sigaddset(&sigmaskbits, SIGTERM);
sigaddset(&sigmaskbits, SIGHUP);
sigaddset(&sigmaskbits, SIGXCPU);
sigaddset(&sigmaskbits, SIGPIPE);
/// http://man7.org/linux/man-pages/man2/sigprocmask.2.html
if (sigprocmask(SIG_UNBLOCK, &sigmaskbits, nullptr))
HCV_FATALOUT("hcv_start_background_thread: sigprocmask failure");
HCV_DEBUGOUT("hcv_start_background_thread sigprocmask done");
hcv_bg_signal_fd = signalfd(-1, &sigmaskbits, SFD_NONBLOCK | SFD_CLOEXEC);
if (hcv_bg_signal_fd < 0)
HCV_FATALOUT("hcv_start_background_thread: signalfd failure");
HCV_DEBUGOUT("hcv_start_background_thread hcv_bg_signal_fd=" << hcv_bg_signal_fd);
}
, а функция hcv_background_thread_body
имеет событие l oop делает
while (!hcv_should_stop_bg_thread.load())
{
struct pollfd polltab[4];
memset(&polltab, 0, sizeof(polltab));
polltab[0].fd = hcv_bg_event_fd;
polltab[0].events = POLL_IN;
polltab[1].fd = hcv_bg_signal_fd;
polltab[1].events = POLL_IN;
polltab[1].fd = hcv_bg_timer_fd;
polltab[1].events = POLL_IN;
HCV_DEBUGOUT("hcv_background_thread_body before poll");
int nbfd = poll(polltab, 3,
hcv_debugging.load()?(2*HCV_BACKGROUND_TICK_TIMEOUT):HCV_BACKGROUND_TICK_TIMEOUT);
и позже в том же событии l oop
if (nbfd>0) /* some file descriptor is readable */
{
HCV_DEBUGOUT("hcv_background_thread_body: after poll nbfd:" << nbfd);
if ((polltab[0].revents & POLL_IN) && polltab[0].fd == hcv_bg_event_fd)
{
int64_t evrk=0;
HCV_DEBUGOUT("hcv_background_thread_body pollable hcv_bg_event_fd="
<< hcv_bg_event_fd);
int byrd = read (hcv_bg_event_fd, &evrk, sizeof(evrk));
if (byrd==sizeof(evrk))
{
HCV_DEBUGOUT("hcv_background_thread_body: got " << evrk
<< " from hcv_bg_event_fd=" << hcv_bg_event_fd);
hcv_bg_do_event(evrk);
}
else
HCV_SYSLOGOUT(LOG_WARNING,
"hcv_background_thread_body read hcv_bg_event_fd#" <<hcv_bg_event_fd << " failed, byrd=" << byrd);
};
if ((polltab[1].revents & POLL_IN) && polltab[1].fd == hcv_bg_signal_fd)
{
HCV_DEBUGOUT("hcv_background_thread_body pollable hcv_bg_signal_fd="
<< hcv_bg_signal_fd);
struct signalfd_siginfo signalinfo;
memset (&signalinfo, 0, sizeof(signalinfo));
int byrd = read(hcv_bg_signal_fd, &signalinfo, sizeof(signalinfo));
if (byrd < 0)
HCV_FATALOUT("hcv_background_thread_body: failed read of hcv_bg_signal_fd="
<< hcv_bg_signal_fd);
else if (byrd != sizeof(signalinfo))
// should never happen... see signalfd(2)
HCV_FATALOUT("hcv_background_thread_body: corrupted read of hcv_bg_signal_fd="
<< hcv_bg_signal_fd << ", byrd=" << byrd);
HCV_DEBUGOUT("hcv_background_thread_body: got signalinfo #" << signalinfo.ssi_signo
<< " from hcv_bg_signal_fd=" << hcv_bg_signal_fd);
if (signalinfo.ssi_signo == SIGTERM)
{
HCV_SYSLOGOUT(LOG_NOTICE, "hcv_background_thread_body got SIGTERM at "
<< (hcv_monotonic_real_time() - hcv_monotonic_start_time)
<< " elapsed seconds");
hcv_process_SIGTERM_signal();
hcv_should_stop_bg_thread.store (true);
}
Но hcv_process_SIGTERM_signal
никогда не вызывали.
Что такое Я делаю не так?