Основная обработка сигналов в C ++ - PullRequest
12 голосов
/ 29 сентября 2010

Это довольно простой сценарий, но я не нахожу слишком много полезных ресурсов.У меня есть программа C ++, работающая в Linux, которая выполняет обработку файлов.Читает строки, выполняет различные преобразования, записывает данные в базу данных.Есть определенные переменные (хранящиеся в базе данных), которые влияют на обработку, которую я в настоящее время читаю на каждой итерации, потому что я хочу, чтобы обработка была как можно более актуальной, но небольшая задержка - это нормально.Но эти переменные меняются довольно редко, и чтения со временем обходятся дорого (10 миллионов плюс строки в день).Я мог бы распределить чтения для каждой n итераций или просто перезапустить программу, когда переменная изменится, но они кажутся хакерскими.

Вместо этого я хотел бы, чтобы программа вызывалаперечитайте переменные, когда получите SIGHUP.Все, что я читаю об обработке сигналов, говорит о библиотеке сигналов C, которую я не знаю, как связать с классами моей программы.Библиотеки сигналов Boost, похоже, больше связаны с межобъектной связью, чем с обработкой сигналов ОС.

Кто-нибудь может помочь?Кажется, что это должно быть невероятно просто, но я довольно ржавый с C ++.

Ответы [ 4 ]

16 голосов
/ 29 сентября 2010

Я бы справился с этим так же, как вы могли бы справиться с этим в 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`.

3 голосов
/ 29 сентября 2010

Я бы рекомендовал проверить эту ссылку , которая дает подробную информацию о регистрации сигнала.

Если я не ошибаюсь, важно помнить, что любая функция внутри объекта ожидает параметр-референт, что означает, что нестатические функции-члены не могут быть обработчиками сигналов. Я считаю, что вам нужно зарегистрировать его либо в статической функции-члене, либо в какой-то глобальной функции. Оттуда, если у вас есть конкретная объектная функция, о которой вы хотите позаботиться об обновлении, вам потребуется способ ссылки на этот объект.

1 голос
/ 29 сентября 2010

Есть несколько возможностей; реализация всех их не обязательно была бы излишней:

  • Отвечать на определенный сигнал, точно так же, как С. C ++ работает так же. См. Документацию для signal().
  • Запуск по метке времени изменения некоторых файлов, например, базы данных, если она хранится в плоском файле.
  • Триггер один раз в час или один раз в день (что имеет смысл).
0 голосов
/ 29 сентября 2010

Вы можете определить сигнал Boost, соответствующий сигналу OS, и привязать сигнал Boost к вашему слоту, чтобы вызвать соответствующий обработчик.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...