2013-08-22 95 views
2

我最近开始使用信号进行编程。我用他们在C.我的多线程服务器的代码下面是代码相关的信号的一部分,但它不工作,因为它应该做的:为什么此代码无法按预期工作?

信号处理程序:

void* Ctrl_C_handler(void *arg) 
{ 
int *sock_fd_ptr = (int*)arg; 
sigset_t set; 
int err, sig; 

err = sigemptyset(&set);    // Clear the signals holder set 
if(err) perror("sigemptyset(&set)"); 

err = sigaddset(&set, SIGINT);   // Add the SIGINT: Ctrl+C 
if(err) perror("siaddset(&set, SIGINT)"); 

err = pthread_sigmask(SIG_UNBLOCK, &set, NULL); // Set mask as to unblock SIGINT 
if(err) perror("pthread_sigmask(SIG_SETMASK, &set, NULL)"); 

printf("Signal handler active:\n"); 
while(1)  // Ctrl+C 
{ 
    err = sigwait(&set, &sig);   // Wait for signal to occur 
    if(err) 
    { 
     perror("sigwait(&set, &sig)"); 
     printf("Error handling the signal, SigHandlerThread exiting..\n"); 
     break; 
    } 

    if(sig == SIGINT) 
    { 
     printf("Ctrl+C detected by server !!\n"); 
     printf("No more connections will be accepted!!"); 
     if(*sock_fd_ptr > 0) 
     { 
      close(*sock_fd_ptr); 
      *sock_fd_ptr = -1; 
      break; 
     } 
    } 
} 
return NULL; 

}

在main():

/*********** Signal Handling *************/ 

sigset_t set;      // declare a set to hold the signals 
err = sigfillset(&set);    // Fill the set with all the signals 
if(err) perror("sigfillset(&set)"); 

err = sigthreadmask(SIG_BLOCK, &set, NULL); // Block/Mask the signals in the set 
if(err) perror("sigthreadmask(SIG_BLOCK, &set, NULL)"); 

err = pthread_create(&sig_handler_tid, NULL, Ctrl_C_handler, (void *)&sock_fd); 
            // Create a thread for handling signals 
if(err) perror("pthread_create"); 

我读这个方法here。我尝试从不同的终端窗口发送kill -s SIGINT <pid of my program>,但程序退出。

+0

你在信号处理程序中做得太多了。请记住,你的程序中断了!那么你真的想要(1)吗?也不是printf,也不perror是异步信号安全的。 – zoska

回答

1

当SIGINT发送到您的进程时,它将被传递到解除阻塞的唯一线程,即您的Ctrl_C_handler线程。信号传递意味着采取与信号相关的任何动作,正如你所知,SIGINT的默认动作是处理终止。

但是,为什么不按照你的意愿冷静地截获信号?

sigwait()设计为remove a signal from a mask of pending signals - 也就是说,生成的信号的传递被暂停(SIG_BLOCKed) - 没有通常的异步信号传输戏剧。

所以,不要在你的线程中使用SIG_UNBLOCK SIGINT。相反,保持它被阻止,并且代码将按照你的意图工作。如果仔细检查您提供的参考,您会发现在调用sigwait()之前,示例代码会阻止所有信号。

相关问题