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),“返回值”。
但为什么然后它有时打印“B”? –