クライアントが送信したものをエコーバックするマルチスレッドサーバーアプリケーションを作成しています。新しいクライアントごとに 1 つのスレッドを生成しています。ループを使用して、while(1)
連続するクライアントを無期限に処理しました (正確には無期限ではありません。強制的に 64 に制限し、その後は新しい接続を拒否しました)。ここで、サーバー アプリケーションで Ctrl+C シグナルを処理する必要があります。
1 つの問題は、マルチスレッド アプリケーションでの使用が推奨されないことです。signal()
ただし、 SO で既に説明しSIGINT
た方法を使用して (Ctrl+C から) シグナルをキャッチするために使用したとしても、これを行う必要があります
。1) サーバーはこれ以上クライアントを受け入れません。
2) クライアントが切断を選択した場合を除き、サーバーへの現在の接続は継続する必要があります。
私のシグナルハンドラ関数は次のとおりです。
void Ctrl_C_handler(int sig)
{
if(sig == SIGINT) // Ctrl+C
{
printf("Ctrl+C detected by server !!\n");
printf("No more connections will be accepted!!");
pthread_cancel(main_thread_id);
}
}
スレッドをキャンセルするために main() 内で使用することを提案するメソッドは次のとおりです。
// Method 1
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
while(1)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
// ..
// client handling
// ..
}
// Method 2
while(1)
{
pthread_testcancel(); // Create Cancellation point
// ..
// client handling
// ..
}
// Method 3
while(1)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_testcancel();
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
// ..
// client handling
// ..
}
私が使用している理由pthread_cancel()
:
このリンクによると、スレッドはpthread_exit()
(要件 1 が満たされている) を使用して最終的に終了します。のNOTES セクションでpthread_exit()
は、他のスレッドが実行を継続できると説明しているため (要件 2 が満たされている)。
今ここまで正しければ、
スレッドのキャンセルに最適な方法はどれですか。
方法 3 を選択した理由は次のとおりです。
(デメリット) 方法 1: スレッドがメモリを割り当てる場合、非同期スレッドのキャンセルは安全ではありません (SO の回答で見たように)。その他の理由はほとんどありません。
(デメリット) 方法 2:このリンクによると、キャンセル ポイントとしても機能する関数が他にもたくさんあります。そのうちのいくつかをコードで使用します。
(メリット) 方法 3: 方法 2 に似ていますが、スレッドがキャンセル不可であるため、他のキャンセル ポイントがアクティブにならないため安全です。
私のやり方が正しいか教えてください。pthread_cancel() を使用する以外に、Ctrl+C を同様に処理するためのより良い方法はありますか?