2011-11-01 99 views
0

我有一个在单线程C应用程序中定义的关闭钩子处理程序。关闭C应用程序以确保完成CRITICAL部分的正确方法?

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 )”循环只是连续运行...

本质的大型服务器上,如果我打CRTL-C以下是时间可持续输出到屏幕:

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

也许我需要在这里创建线程,并在它们之间进行相互通信,但是它们没有更简单的方法来优雅地允许“共享库中的循环”在关闭之前结束它的“关键代码/事务”,即使在极速服务器?为什么它在我的linux笔记本电脑上工作?

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

感谢您的帮助,非常感谢

林顿

+0

什么在您的Linux机器上将'transactionRunning'设置为FALSE?如果它是一个单线程应用程序,它不会改变它的'sleep/printf'循环... –

+1

通常,在信号处理程序(或I/O)中执行长时间运行的任务并不是一个好主意。而是在信号处理程序中发送一个“信号”给主线程并完成所有工作。 –

+0

正如你所说的应用程序是单线程的,当应用程序在SIGINT处理程序中循环并等待时,共享库没有机会退出其循环。一个明显的事实是,它看起来好像它会按照你希望它应该在你的Linux机器上那样工作,尽管它不应该。服务器上的行为对我来说看起来完全没问题。 – alk

回答

2

确保running(和transactionRunning也被声明为volatile)。否则,在某些情况下,C编译器可能会缓存它的值。现在,想到volatile意思是“该值可以通过信号处理程序进行更改”。

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

rc = wmq_sender_stop(errorStr); 

如果你这样做,在信号处理程序,你最好希望,这一功能是安全地从信号处理程序调用。大部分功能都没有。 (甚至可以安全地从多个线程调用的函数对于来自信号处理程序的调用是不安全的。)

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

+0

好点:我完全同意宣布'运行'不稳定。如果你已经解释了为什么'wmq_sender_stop'可能会被unsafed从信号处理程序中调用,我会投你的答案。 – alk

+0

@alk:我对“wmq_sender_stop”一无所知,所以我没有理由认为它是安全的。从信号处理程序调用大多数函数是不安全的(例如,包括'printf')。没有必要告诉人们你隐瞒upvotes,你可以要求澄清。 –

+0

好吧,假设最糟糕的情况是最安全的方法,谢谢澄清... - 请原谅我关于投票的不相干的附注。 – alk

0

为什么不叫wmq_sender_stop(),比通过return离开信号处理程序。共享库中的循环将退出,所以你的应用程序将会这样做,不是吗?

+0

但是没有时间问题呢?如果主应用程序在shard lib中的循环结束之前结束,会发生什么情况? –

+0

@Lynton Grice为什么应该主要的应用程序结束? – alk

相关问题