Используйте sigaction (), чтобы разрывать бесконечные циклы в C ++ без глобальных переменных

0

Я работаю над демоном, который слушает нажатия клавиш. Я использую системный вызов epoll_wait(), который блокирует цикл, пока что-то не произойдет на устройстве. Несмотря на то, что он суперэффективен по ресурсам, он значительно усложняет выход из основного цикла. На данный момент у меня есть рабочее решение с использованием глобальной переменной. Однако я хочу исключить глобальную переменную, но не нашел эффективного способа сделать это. Это мой (упрощенный) код:

/* global variables */
volatile sig_atomic_t run;

void sig_handler(int sig) {
    switch (sig) {
        case SIGINT:
            run = 0;
            break;
        case SIGTERM:
            run = 0;
            break;
        default:
            std::cout << "Unknown signal received." << std::endl;
    }
}

int main(int argc, char *argv[]) {
    /* signal handling */
    struct sigaction action;
    action.sa_handler = sig_handler;
    sigaction(SIGINT, &action, NULL);
    sigaction(SIGTERM, &action, NULL);

    run = 1;

    /* main loop */
    while (run) {
        epoll_wait(epoll_fd, &epoll_ev, MAX_EVENTS, -1);
        /*
         * epoll_wait() unblocks the loop, because an input has been
         * registered. We use read() to check the input.
         */
        process_input(get_input());
    }

    return EXIT_SUCCESS;
}

Вы можете найти полный код здесь: https://github.com/tolga9009/sidewinderd. Как бы вы решили?

  • 0
    Нет ничего более эффективного. Целесообразно использовать глобальную переменную для глобального состояния.
  • 0
    Спасибо, может быть, я просто оставлю это как сейчас. Мне все еще интересно, есть ли какой-нибудь способ C ++, чтобы решить этот, или другой, более элегантный способ.
Показать ещё 1 комментарий
Теги:
loops
signals
daemon

1 ответ

0

Один из вариантов использует fork, чтобы родитель продолжал прослушивать (принимать) новые события, в то время как ребенок работает с прибывшими событиями.

  • 0
    Хотя это очень интересная идея, она не отвечает на вопрос. Как бы вы нарушили родительский цикл для сигналов SIGINT & SIGTERM, не используя глобальную переменную?
  • 0
    Проект на основе форка не требует использования глобальной переменной. Однако для логики, основанной на цикле while, глобальная переменная является выбором. Лучший вариант дизайна, основанный на цикле while, не зависящем от глобальной переменной, может заключаться в использовании while (1) над epoll с условным разрывом / продолжением в коде.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню