【问题标题】:Use sigaction() to break infinite loops in C++ without global variables使用 sigaction() 在没有全局变量的情况下打破 C++ 中的无限循环
【发布时间】:2014-12-28 23:35:44
【问题描述】:

我正在开发一个监听按键的守护进程。我正在使用 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。你会怎么解决呢?

【问题讨论】:

  • 没有比这更有效的了。对全局状态使用全局变量是合适的。
  • 谢谢,也许我会保持原样。我仍然想知道,是否有任何“C++ 方式”来解决这个问题,或者另一种更优雅的方式。
  • 使其“更多 C++”的唯一更改是使用 std::atomic&lt;bool&gt; 而不是 sig_atomic_t

标签: c++ linux loops signals daemon


【解决方案1】:

一种选择是使用 fork,以便父级继续侦听(接受)新事件,而子级对到达的事件进行操作。

【讨论】:

  • 尽管这是一个非常有趣的想法,但它并不能回答问题。在不使用全局变量的情况下,如何打破 SIGINT 和 SIGTERM 信号的父循环?
  • 基于分叉的设计不需要使用全局变量。但是,对于基于 while 循环的逻辑,全局变量是一种选择。基于独立于全局变量的 while 循环的更好的设计选项可以是通过在代码中使用带有条件中断/继续的 while(1) 而不是 epoll。
猜你喜欢
  • 2020-08-18
  • 2015-12-10
  • 1970-01-01
  • 1970-01-01
  • 2017-10-30
  • 1970-01-01
  • 1970-01-01
  • 2019-10-02
  • 1970-01-01
相关资源
最近更新 更多