2017-06-19 12 views
1

CとUNIXで書かれた汎用プログラムをビルドしています(Linuxを使用しているので、BSD関数やWIN関数は気にしません) 。SIGINTが呼び出されたときにスレッドを終了する - C

void init_threads(int socket_desc) { 

    pthread_t chat_threads[2]; 

    ret = pthread_create(&chat_threads[0], NULL, receiveMessage, (void*)(long)socket_desc); 
    PTHREAD_ERROR_HELPER(ret, "Errore creazione thread ricezione messaggi"); 

    ret = pthread_create(&chat_threads[1], NULL, sendMessage, (void*)(long)socket_desc); 
    PTHREAD_ERROR_HELPER(ret, "Errore creazione thread invio messaggi"); 

} 

このプログラムは、私はCTRL-Cの可能性を実装するシェルから起動されますので、私はこのコード行で行ったので:

signal(SIGINT,kill_handler); 
// and its related function 
void kill_handler() { 
     // retrive threads_id 
     // call pthread_exit on the two threads 
     printf("Exit from program cause ctrl-c, bye bye\n"); 
     exit(EXIT_SUCCESS); 
     } 

私の質問は、私がどのように見出すことができていますスレッドIDはイベントハンドラ関数の中にあり、pthread_exitを呼び出すのは正しいですか?何か他のものを使うべきですか?

+2

[シグナルハンドラでスレッドを正しく終了させるにはどうすればいいですか?](https://stackoverflow.com/questions/25950621/how-to-properly-terminate-a-thread-in-a-signal-ハンドラ) – Gaurav

+1

シグナルはメインスレッドに配信されます。そこにexit()するだけで、OSはあなたのためにクリーンアップを行います。 – Ctx

+0

ディープサーチの20分後に重複が見つかりませんでした。私のプログラムではソケットを使用しているので、Felix Palmenの答えは@Ctxのコメントよりも優れていると評価されています。ソケットが開いていると、ソケットが聞こえなくても短時間ソケットが開かれます。とにかく、みんなに感謝します。 – Thecave3

答えて

2

pthread_exit()をシグナルハンドラから呼び出さないでください! 非同期信号安全である必要はありません。signal-safetyを参照してください。

通常、信号ハンドラではのようにできるだけ少なくしてください。一般的なイディオムは、メインループで定期的にチェックされるフラグを設定するだけです。

volatile sig_atomic_t exitRequested = 0; 

void signal_handler(int signum) 
{ 
    exitRequested = 1; 
} 

int main(void) 
{ 
    // init and setup signals 

    while (!exitRequested) 
    { 
     // do work 
    } 

    // cleanup 
} 

また、シグナルハンドラのインストールにはsigaction()を使用してください。それを使用しない理由はsignal()を参照してください。

+0

便利なリンクと説明をありがとう – Thecave3

+0

私の質問とは無関係ですが、sig_atomic_t型は何ですか?また、なぜint型ではなく使用したのですか?私は整数が32ビットマシンで4バイトであることを知っています、これはより厳しいですか? – Thecave3

+1

これは* single *命令での読み書きを保証するタイプです。 int型の 'typedef'でも良いチャンスがありますが、' int'が読み書きのために複数の命令を必要とするシステムがあるかもしれません(例えば 'int'が16ビットの8ビットアーキテクチャで) - シグナルハンドラとメインプログラムとの間の一貫した値のためには、常に 'volatile sig_atomic_t'を使用してください。 –

関連する問題