2011-02-24 14 views
1

私は、スレッドプールを持つマルチスレッドサーバを設計しています。このシステムは、クライアントが24/7に近い接続を維持するため、固定TCP接続を使用するように設計されています。私が遭遇する問題は、シャットダウンを管理する方法です。現在、接続は「accept(listen_fd ....)」を介して行われ、作業指示書構造体に割り当てられます。この構造体は作業キューにダンプされ、スレッドによって取得されます。この時点から、このスレッドは現在の接続に専念しています。スレッド内の私のコードは次のとおりです。単にソケットに耳を傾け、無期限に文字をエコー表示し、クライアントが接続を終了したときに、正常に動作しシャットダウン固定TCPコネクション。 (Cマルチスレッドサーバ)

/* Function which runs in a thread to handle a request */ 
void * 
handle_req(void *in) 
{ 
    ssize_t n; 
    char read; 
    /* Convert the input to a workorder_ptr */ 
    workorder_t *workorder_ptr = (workorder_t *)in; 

    while(!serv_shutdown 
     && (n=recv(workorder_ptr->sock_fd,&read,1,0) != 0)) 
    { 
    printf("Read a character: %c\n",read); 
    } 
    printf("Peer has shutdown.\n"); 

    /* Free the workorder memory */ 
    close(workorder_ptr->sock_fd); 
    free(workorder_ptr); 
    return NULL; 
} 

。 whileループに "!serv_shutdown"の部分があります。これは、スレッドがシャットダウン信号でループを抜け出そうとした私の試みです。 SIGINTが捕捉されると、グローバル変数は1に設定されます。残念ながら、プログラムは現在recv文でブロックしており、別の文字が読み込まれるまでこのフラグをチェックしません。この接続で別の文字が送信されるまでには、任意の時間がかかる可能性があるので、これを避けたいと思います。

また、別の記事では、ソケット接続を待つために「受け入れる」よりも「選択する」方が良いと思っていますが、わかりませんでした。あなたは待つ選択をして、それからすぐに受け入れをしますか?どのようにselectがソケット接続を作成するのか分かりません。私はこれを尋ねます。なぜなら、私の選択の理解がクリアされていれば、おそらくそれは私が求めている質問に当てはまるでしょうか?

また、接続が単にタイムアウトするケースを検出するにはどうすればよいですか?

ありがとうございます!私は最終的にはさらに掘削した後、解決策を見つけたかもしれないと思う

EDIT

Wake up thread blocked on accept() call

基本的に、私は世界のパイプを作成し、各スレッドを持つことができますが、独自のsocket_fd上の選択を行いますこのグローバルパイプも同様です。それで、信号が捕まえられると、私はパイプに何かを書くだけです。すべてのスレッドは起床する必要がありますか?

答えて

1

FreeBSD、MacOSX、そしておそらくどこか他の場所にkevent()コールがあり、これは接続要求やデータがソケットに到着したときのシグナリングなど、幅広いシステムイベントを監視することができます。 それはあなたの問題のすべてをきちんと解決しますが、移植性がありません。 libeventやlibevのようなlibsがあり、BSDのkevent()、Linuxのepoll()などのOS固有の機能を包み込んでいます。それがあなたを助けるかもしれない。

関連する問題