C:信号处理和信号灯

问题描述:

我试图更好地理解信号量和所有爵士乐,并且我正在编程使用共享内存和信号量进行通信的服务器和客户端。它工作得很好,一切都很顺利,但我不确定我是否理解信号处理在这种情况下如何正常工作。这是我的服务器的一些示例代码。我意识到这可能是一个有点多余同时检查,但我还挺想了解怪异的行为我遇到: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 
    } 
} 

服务器是服务器旗号,客户端是客户端旗号(其没有按在这种情况下真的很重要)。运行(这实际上是全球性)是我在信号处理程序使用的变量:

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.这看起来完全是随机的。它有点迫使我使用运行变量,因为有时候,信号量会通过,而在其他时候,它不会。

由于您没有处理来自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程序,你可以终止你的服务器正常,你跳到循环的开始,请参阅运行设置为0,跳过循环。

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

+0

但为什么然后它有时打印“B”? –