10

C で記述されたマルチスレッド サーバーがあり、各クライアント スレッドは次のようになります。

ssize_t n;
struct request request;

// Main loop: receive requests from the client and send responses.
while(running && (n = recv(sockfd, &request, sizeof(request), 0)) == sizeof(request)) {
    // Process request and send response.
}
if(n == -1)
    perror("Error receiving request from client");
else if(n != sizeof(act))
    fprintf(stderr, "Error receiving request from client: Incomplete data\n");

// Clean-up code.

ある時点で、クライアントは切断しなければならない特定の基準を満たします。クライアントが定期的にリクエストを送信している場合、応答で切断を通知できるため、これは問題ありません。ただし、クライアントが要求を送信するのに時間がかかる場合があるため、クライアント スレッドがrecv呼び出しでブロックされ、クライアントは次の要求/応答まで切断されません。

recvクライアント スレッドが呼び出しでブロックしている間にクライアントを別のスレッドから切断するクリーンな方法はありますか? 試してみましたが、実際には正確ではないclose(sockfd)エラーが発生します。Error receiving request from client: Bad file descriptor

または、ここでエラーを処理するためのより良い方法はありますか?

4

3 に答える 3

10

したがって、少なくとも次の可能性があります。

(1) errno == EINTRpthread_killでスレッドを吹き飛ばし、recv自分でスレッドをクリーンアップして終了できます。これを嫌だと思う人もいます。依存します、本当に。

(2) クライアントソケットをノンブロッキングにしselect、スレッド間で使用されるスイッチがシャットダウンするように設定されているかどうかを確認する前に、特定の時間入力を待機するために使用します。

(3) (2) と組み合わせて、各スレッドがマスタースレッドとパイプを共有するようにします。に追加しselectます。読み取り可能になり、shutdonw 要求が含まれている場合、スレッドはそれ自体をシャットダウンします。

(4)pthread_cancel上記(またはそのバリエーション)のいずれもニーズを満たさない場合は、メカニズムを調べてください。

于 2013-07-23T22:43:13.457 に答える
4

別のスレッドからの入力のためにソケットをシャットダウンします。これにより、読み取りスレッドが EOS を受信し、正しく書き込まれていればソケットを閉じて終了します。

于 2013-07-24T00:34:47.620 に答える