【问题标题】:C: Signal handling and semaphoresC:信号处理和信号量
【发布时间】:2016-01-21 18:17:46
【问题描述】:

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

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 是客户端信号量名称(在这种情况下并不重要)。 running(实际上是全局的)是我在信号处理程序中使用的变量:

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。这似乎是完全随机的。不过,这有点强迫我使用 running 变量,因为有时,信号量会被传递,而在其他时候,它不会。

【问题讨论】:

    标签: c semaphore signal-handling


    【解决方案1】:

    由于您不处理来自sem_wait(3)EINTR,因此行为与应有的完全一样。

    例如,您在 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),“返回值”。

    【讨论】:

    • 但是为什么它有时会打印“B”?
    猜你喜欢
    • 2021-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 1970-01-01
    • 2014-01-08
    相关资源
    最近更新 更多