Допустим, у меня есть сервер, который в бесконечном цикле что-то читает с помощью блокирующей функции (например, read или accept). И вот наступает момент, когда новой информации не поступает (то есть процессу read нечего больше читать, например) и нам нужно этот процесс корректно завершить с помощью SIGTERM, отправленного через терминал. Если я напишу обработчик этого сигнала и установлю его изначально с помощью системного вызова signal, то я ничего особо сделать не смогу (чтобы, например, закрыть используемые файлы, мне нужно делать их дескрипторы глобальными переменными, что не очень хорошо и т.д. и т.п.) - обработчик закончит своё выполнение и всё вернётся обратно на строчку с блокирующим вызовом. Какой принцип обработки таких случаев считается хорошим? Самый простое решение такой проблемы - использовать неблокирующие вызовы, но неужели нельзя никак «разбудить» такой процесс? Я пытался найти решение этой проблемы, но там обычно предлагают поставить таймер и таким образом просто завершать процесс, когда он долго ничего не читает (хотя опять же, тут нужно писать обработчик сигнала, из-за чего возникают проблемы, уже описанные мной выше). Мне такой подход не очень нравится - я хочу, чтобы сервер мог ждать нового сообщения хоть месяц. Вот пример кода, если не очень понятно, что я имею в виду:
void sig_handler(int num) {
if(num == SIGTERM) {
// Тут я что-то сделаю и обратно попаду на строчку с accept,
// после чего продолжу там висеть, пока не придёт новый запрос
}
}
int main(void) {
...
signal(SIGTERM, sig_handler);
...
while(1) {
// Пока новый запрос не придёт, процесс будет висеть на этой строчке
int ns = accept(s, (struct sockaddr*)&clnt_addr,
&clnt_addrlen);
...
}
...
}