2013-01-09 28 views
0

我正在使用libpq库编写一个用于将数据发布到PostgreSQL数据库的守护进程。 它具有这样的结构:如何在用户终止程序时关闭初始化连接

init(...) // init function, opens connection 
while(1){export(...)} // sends commands 

当有人杀死了应用程序,它留下的PostgreSQL服务器上打开的连接。我想避免这种情况。在导出(...)函数中打开和关闭连接不是一种选择,因为此代码是性能依赖框架的一部分。

回答

1

您可以安装一个signal handler赶杀的应用,并从该处理程序关闭活动连接:

#include "signal.h" 
#include "stdio.h" 
#include "stdlib.h" 

void catch_sigint(int sig) 
{ 
    /* Close connections */ 

    /* 
    * The software won't exit as you caught SIGINT 
    * so explicitly close the process when you're done 
    */ 
    exit(EXIT_SUCCESS); 
} 

int main(void) 
{ 
    /* Catches SIGINT (ctrl-c, for instance) */ 
    if(signal(SIGINT, catch_sigint) == SIG_ERR) 
    { 
     /* Failed to install the signal handler */ 
     return EXIT_FAILURE; 
    } 

    /* Perform your operations */ 
    while(1); 

    return EXIT_SUCCESS; 
} 
+0

使用信号的'()'不推荐,因为不是便携式的。应该避免使用它。如果可用,sigaction()是首选解决方案。 – alk

+0

错! 'signal'是ISO-C,'sigaction'是POSIX。所以'信号'实际上更加便携。但我同意这是旧的方式,比'sigaction'选项少。但是,在大多数实际的POSIX系统上也要注意,'signal'实际上是通过'sigaction'实现的。我在答案中使用了'signal',因为OP没有提及它的平台,所以这个例子甚至可以在非POSIX系统上运行。 – Macmade

+0

当提到一个POSIX函数作为替代时,我不应该写“* ... portable ... *”,你是对的(尽管我添加了“* ...如果可用... *”免责声明,顺便说一句) 。无论如何,即使是ISO-C,这也不能确保'signal()'的每个实现的行为类似。 – alk

1

你必须实施,可以终止你的节目信号的处理程序。

void handler_function(int signal) { 
    //close db connection 
    exit(signal); 
} 

    // somewhere in init: 
{ 
    sigset_t sigs; 
    struct sigaction siga_term; 

    sigfillset(&sigs); 

    siga_term.sa_handler = handler_funciton(); 
    siga_term.sa_mask = sigs; 
    siga_term.sa_flags = 0; 

    sigaction(SIGTERM, &siga_term, NULL); 
} 

请教how to intercept linux signals ? (in C)

相关问题