正确关闭C应用程序以确保CRITICAL部分完成的方法?

时间:2011-11-01 06:52:40

标签: c signals

我在SINGLE线程C应用程序中定义了一个关闭钩子处理程序。

int main(int argc, char * argv[]){
    //Shutdown hook for CTRL-C
    (void) signal(SIGINT, shutdownHook);
    ...
    ...
}

因此,当用户点击CTRL-C时,会启动关闭挂钩...

void shutdownHook(int sig){
    rc = wmq_sender_stop(errorStr);
    if (rc != 0){
        printf("\n%s\n", errorStr);
    }
    while(transactionRunning == TRUE){
        sleep(1);
        printf("Transaction still running\n");
    }
    ....
    ....
}

你可以在上面看到我调用了一个“wmq_sender_stop”例程(在共享库中),该例程实际上将一个变量设置为FALSE以结束该共享库中的循环。

int wmq_sender_stop(char errorStr[ERROR_STR_LEN]){
       running = FALSE;
       ...
}

并且该变量“running”将停止(希望)在该共享库中运行的主循环。

while(running == TRUE){
...
...
}

我所拥有的问题是在我的Linux机箱上100%全部工作......但是当我在一个强大的服务器上安装应用程序时,它调用“wmq_sender_stop”并设置变量很好,但似乎应用程序是在服务器上运行得太快以允许“while(running == TRUE)”变量退出.....或者它只是过快地返回主应用程序并且“while(transactionRunning == TRUE)”循环只是不断奔跑......

基本上在BIG服务器上如果我点击CRTL-C,则以下是连续输出到屏幕:

Transaction still running
Transaction still running
Transaction still running
Transaction still running
Transaction still running
Transaction still running
...

也许我需要在这里创建线程并在它们之间进行相互通信,但它们是否更容易优雅地允许“共享库中的循环”结束它的“关键代码/事务”,甚至在极速服务器上关闭之前?为什么它在我的linux笔记本电脑上运行?

如果我需要使用线程,那么他们最好和最快的方式是什么?目前我正在使用CALLBACKS ....但我不确定最好的IPC是什么?

感谢您的帮助,非常感谢

林顿

2 个答案:

答案 0 :(得分:2)

确保将running(以及transactionRunning)声明为volatile。否则,C编译器可能会在某些情况下缓存其值。现在,将volatile视为“信号处理程序可以更改此值”。

请注意,您必须小心这样的代码:

rc = wmq_sender_stop(errorStr);

如果你在信号处理程序中这样做,你最好希望从信号处理程序调用该函数是安全的。大多数功能都没有。 (即使从多个线程调用安全的函数也不容易从信号处理程序调用。)

最后一个问题是,如果您的代码是单线程的,但您永远不会从信号处理程序返回,那么您的主循环应该如何退出?信号处理程序在您的应用程序的一个现有线程中运行。通常,您希望在信号处理程序中执行的唯一操作是更改标记为volatile的全局变量的值,然后返回。

答案 1 :(得分:0)

为什么不调用wmq_sender_stop()而不是通过return离开信号处理程序。共享库中的循环将退出,因此您的应用程序将执行,不是吗?