C:信号处理和信号量

塑造

我试图更好地理解信号量和所有爵士乐,为此,我正在对使用共享内存和信号量进行通信的服务器和客户端进行编程。它工作得很好,并且一切正常,但是我不确定在这种情况下信号处理如何正常工作。这是我服务器上的一些示例代码。我意识到同时检查这两者可能有点多余,但是我有点想了解我正在经历的怪异行为:

sig_atomic_t running = 1;

while(running == 1) {
    if (sem_wait(server) == -1) {
        //exit and print error A
    }
    if(running == 0) {
        //exit and print error B
    }
    /* do server stuff */

    if (sem_post(client) == -1) {
        //exit and print error
    }
}

server是服务器信号灯名称,client是客户端信号灯名称(在这种情况下,这并不重要)。运行(实际上是全局的)是我在信号处理程序中使用的变量:

static void init_signalhandler() {
    struct sigaction sa;
    sa.sa_handler = terminate;

    if(sigemptyset(&(sa.sa_mask)) == -1) {
        bail_out(EXIT_FAILURE, "sigemptyset error");
    }

    if(sigaction(SIGINT, &sa, NULL) == -1) {
        bail_out(EXIT_FAILURE, "sigaction1 error");
    } 

    if(sigaction(SIGTERM, &sa, NULL) == -1) {
        bail_out(EXIT_FAILURE, "sigaction2 error");
    }
}

static void terminate(int e) {
    running = 0;
    sem_post(server);
}

其中bail_out是自定义错误打印/退出功能。

基本上,无论我做什么,只要启动服务器,它都可以发挥sem_wait(server)作用。如果我尝试通过发送SIGINT杀死它,则有时会显示错误A,而有时会显示错误B。这似乎是完全随机的。但是,这有时迫使我使用运行变量,因为有时会传递信号量,而在其他时候却不会。

叛徒

当你不处理EINTRsem_wait(3)行为是完全应该的。

例如,您在sem_wait(server)您得到SIGINT并正确处理它。您的sem_wait函数将返回-1,您将获得纾困。您应该怎么做:

    if (sem_wait(s_server) == -1) {
        if(errno == EINTR) continue;
        bail_out(EXIT_FAILURE, "sem_wait(3) failed");
    }

这将捕获由于sem_wait例程中的信号引起的错误,并且您可以在跳到循环的开始时优雅地终止服务器,看到running设置为0并跳过了循环。

有关可以处理错误的更多详细信息,请参见手册页sem_wait(3),“返回值”。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章