2010-05-18 47 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

相關問題