2014-02-07 62 views
2

我正在使用pthread在C中開發客戶端/服務器。在收到SIGINT或SIGTERM後關閉服務器之前線程的等待終止工作(C中Posix線程)

這是一款紙牌遊戲,其中server是兩個clients之間的玩家。

我這種情況

server.c:使用用於監聽最終進入上accept連接線程調度

  • int main (int argc, char * argv[])

  • pthread_create(&sig_thread, NULL, &thread_signal_handler, &server_Socket);

    線程捕捉內部函數創建信號(方便maskered)

  • pthread_create(&tid[i++], NULL, &worker, (void*) arr_args)

    每個客戶端相關聯,以創建線程(TID是陣列線程 ID)

  • pthread_join(sig_thread, NULL)

    加入線程信號

  • pthread_join(tid[i], NULL)

    加入用於連接每個客戶端創建的線程。

工人:

  • void * worker(void * args)

    做他的工作,並終止

線程信號處理程序:

  • void * thread_signal_handler(void * arg)

無效* thread_signal_handler(無效* ARG){

sigset_t set; 

int sig, n; 

int * socket = (int*) arg; 

sigemptyset(&set); 

sigaddset(&set, SIGINT); 

sigaddset(&set,SIGTERM); 

while (server_UP) 
{ 
    /* wait for a signal */ 
    if (sigwait(&set, &sig)) 
     perror("Sigwait"); 

    /* received SIGINT or SIGTERM - closing server */ 
    if ((sig == SIGINT || sig == SIGTERM))  {  
     printf(TERM_SERVER"\n"); 

    server_UP = 0; /* global variable */ 

    /* close socket blocked on MAIN */ 

    shutdown(*socket, SHUT_RDWR); 
} 

return (void *) EXIT_SUCCESS; 

}

以這種方式,信號被釣到阱和所述服務器是立即終止。 我需要,如果有匹配進行中,等待所有的工作人員完成他們的工作正常,所以我想知道如何說線程處理程序「你收到一個SIGINT(或SIGTERM)?好吧,等待終止所有工作人員「。

有什麼建議嗎?如果你需要更多的代碼,我會編輯這篇文章。

+0

在所有線程上調用'pthread_join()'? – alk

回答

1

創建它們時,可以將所有線程保存在數組或列表中,最後在所有線程上調用pthread_join()。

while (pthread_list) { 
    pthread_join(pthread_list->th_id, NULL); 
    pthread_list = pthread_list->next; 
} 

如果您不想跟蹤所有線程,你可以保持運行的線程的計數,調用在pthread_create之前增加了,減少計數爲每個線程結束。

然後在處理程序中,您會反覆睡眠幾秒鐘,直到計數變爲0.

+0

如果你讀這個'pthread_join(tid [i],NULL)'的簽名,我正好這樣做(我只是使用一個pthread_t數組來代替一個列表)。 'while(i--!= 0) { pthread_join(tid [i],NULL); }' 每當我創建一個線程,我把它放在'tid [i]' 夠了嗎? – Kyrol

+0

是的,夠了。 pthread_join一直等到指定的線程結束,所以如果在退出循環時等待所有線程都完成了所有線程的完成。 – drolando

+0

我將在主循環中進行檢查:如果server_UP == 0,它不應該接受任何新的連接。如果在「加入時」開始後啓動線程,則可能會錯過該線程。所以你也必須在server_UP = 0之後放一段時間; – drolando