我最近开始使用信号进行编程。我在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;
}
Inside 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 :(得分:2)
当SIGINT被发送到您的进程时,它将被传递给唯一一个已解除锁定的线程,即您的Ctrl_C_handler
线程。信号传递意味着采取与信号相关的任何动作,如您所知,SIGINT的默认操作是进程终止。
但是为什么sigwait()不会像你想要的那样冷静地拦截信号?
sigwait()设计为remove a signal from a mask of pending signals - 也就是生成的信号,其传递被暂停(SIG_BLOCKed) - 没有通常的异步信号传递。
所以,不要在你的线程中使用SIG_UNBLOCK SIGINT。相反,保持阻止,代码将按您的意图运行。如果仔细检查您提供的引用,您将看到该示例代码在调用sigwait()之前阻塞所有信号。