2010-05-18 52 views
3

我有一个简单的服务器,它看起来是这样的:如何在使用工作线程模式时正确处理信号?

void *run_thread(void *arg) { 
    // Communicate via a blocking socket 
} 

int main() { 
    // Initialization happens here... 

    // Main event loop 
    while (1) { 
     new_client = accept(socket, ...); 
     pthread_create(&thread, NULL, &run_thread, *thread_data*); 
     pthread_detach(thread); 
    } 

    // Do cleanup stuff: 
    close(socket); 
    // Wait for existing threads to finish 
    exit(0); 
) 

因此,当一个SIGINT或SIGTERM收到我需要打出来的主事件循环的去清理代码。此外,主线程很可能正在等待accept()调用,因此无法检查其他变量以查看是否应该中断;

我发现的大部分建议都是这样的:http://devcry.blogspot.com/2009/05/pthreads-and-unix-signals.html(创建一个特殊的信号处理线程来捕获所有信号并对这些信号进行处理)。然而,这是处理部分,我不能真正包围我的头:我怎么可能告诉主线程从accept()调用返回并检查外部变量,看看它是否应该打破;?

回答

2

通常我在等待select(listeninig-socket-here)不在accept()accept()通常是程序不会花费大量时间等待的方法。当我在select()等待信号SIGTERM发送到该线程(在你的情况下,它是主线程),我退出该selectselect返回interrupted system call

+0

谢谢,这工作的详细信息。 – ipartola 2010-05-18 19:39:48

1

我第二个skwllsp他认为你应该使用select调用而不是接受。但是,我的另外一个建议是,您按照您发布链接的博客的建议,创建一个单独的信号处理线程,并忽略所有其他线程中的信号。然后当信号处理线程收到信号时,使用pthread_cancel取消其他线程。当你使用pthread_cancel时,如果被取消的线程处于取消点(选择恰好是一个),它会出来并进入你的处理程序,你可以清理并退出线程。

你可以找到关于此hereherehere

+0

是的,这就是我最终做的。我还使用了pthread_cleanup_push和pthread_cleanup_pop。奇迹般有效。 – ipartola 2010-05-18 19:42:34

+0

好。其实,pthread_cancel的概念和概念在我看来很出色。 :) – Jay 2010-05-19 05:10:54

相关问题