2010-09-28 3 views
10

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

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

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

ответ

15

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

+1

Oh duh. Я полностью передумал и забыл, что переменные сигнала - это то, что я хочу, а не прямой вызов. * headdesk * – KernelM

+4

Если вы хотите быть совместимым с стандартом, убедитесь, что квалифицируйте обработчик сигнала как «extern» C «' –

+0

@R Samuel: Это отличная точка.Я даже не думал о «extern» C «, так как я писал C-код, но OP понадобится! –

1

Существует несколько возможностей; это не обязательно будет излишним для их реализации:

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

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

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

+0

Этот сайт выглядит закрытым, поэтому вы можете ознакомиться с этой ссылкой (http://www.yolinux.com/TUTORIALS/C++Signals.html). –

+0

Нет, cplusplus.com (и эта ссылка) все еще кажется прекрасным для меня. Всегда хорошо иметь несколько ссылок. – Bryan

0

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

Смежные вопросы