Базовая обработка сигналов в С++
Это довольно простой сценарий, но я не нахожу слишком много полезных ресурсов. У меня есть программа на С++, работающая в Linux, которая обрабатывает файлы. Читает строки, выполняет различные преобразования, записывает данные в базу данных. Существуют определенные переменные (хранящиеся в базе данных), которые влияют на обработку, которую я сейчас читаю на каждой итерации, потому что я хочу, чтобы обработка была как можно более актуальной, но небольшое отставание в порядке. Но эти переменные меняются довольно редко, и чтение со временем дорого (10 миллионов плюс строки в день). Я мог бы пропустить прочитанные на каждую n-итерацию или просто перезапустить программу, когда переменная изменяется, но это кажется хакерским.
Вместо этого я хочу, чтобы программа запускала перечитывание переменных при получении SIGHUP. Все, что я читаю о обработке сигналов, говорит о библиотеке сигналов С, и я не уверен, как привязываться к моим классам программ. Библиотеки сигналов Boost, похоже, больше связаны с межобъектной связью, а не с сигналами ОС.
Может ли кто-нибудь помочь? Похоже, это должно быть невероятно просто, но я довольно ржавый с С++.
Ответы
Ответ 1
Я бы справился с этим так же, как вы могли бы обработать его в C. Я считаю, что совершенно нормально иметь автономную функцию обработчика сигнала, поскольку вы просто отправляете ее в семафор или устанавливаете переменную или некоторые такие, которые другой поток или объект могут проверить, нужно ли перечитывать настройки.
#include <signal.h>
#include <stdio.h>
/* or you might use a semaphore to notify a waiting thread */
static volatile sig_atomic_t sig_caught = 0;
void handle_sighup(int signum)
{
/* in case we registered this handler for multiple signals */
if (signum == SIGHUP) {
sig_caught = 1;
}
}
int main(int argc, char* argv[])
{
/* you may also prefer sigaction() instead of signal() */
signal(SIGHUP, handle_sighup);
while(1) {
if (sig_caught) {
sig_caught = 0;
printf("caught a SIGHUP. I should re-read settings.\n");
}
}
return 0;
}
Вы можете протестировать отправку SIGHUP
с помощью kill -1 `pidof yourapp`
.
Ответ 2
Я бы рекомендовал проверить эту ссылку, которая дает информацию о регистрации сигнала.
Если я ошибаюсь, важно помнить, что любая функция внутри объекта ожидает параметр референта, что означает, что нестатические функции-члены не могут быть обработчиками сигналов. Я считаю, что вам нужно зарегистрировать его либо в статической функции-члене, либо в какой-то глобальной функции. Оттуда, если у вас есть определенная функция объекта, которую вы хотите позаботиться о своем обновлении, вам понадобится способ ссылки на этот объект.
Ответ 3
Существует несколько возможностей; это не обязательно будет излишним для реализации всех из них:
- Отвечайте на конкретный сигнал, как и на C. С++ работает одинаково. См. Документацию для
signal()
.
- Триггер на временной отметке изменения некоторого изменения файла, например, базы данных, если он хранится в плоском файле.
- Триггер один раз в час или один раз в день (что имеет смысл).
Ответ 4
Вы можете определить сигнал усиления, соответствующий сигналу ОС, и связать сигнал усиления с вашим слотом, чтобы вызвать соответствующий обработчик.