2013-11-02 12 views
5

ノンブロッキングソケット(C/C++)とselectを使用してネットワーク通信プログラムを作成しています。プログラムはかなり大きいので、ソースコードをアップロードすることはできません。非常に積極的なテストセッションでは、TCPとUDPの両方を頻繁に開いて閉じるためにテストコードを使用します。 1つのエンドが応答せず、CPU使用率が98または99%を超えています。次に、gdbを付けて添付します。 「bt」は次のとおりです。CPUの消費量が多いselect()の問題は何ですか?

0x00007f1b71b59ac3 in __select_nocancel() at ../sysdeps/unix/syscall-template.S:82 
82 ../sysdeps/unix/syscall-template.S: No such file or directory. 
    in ../sysdeps/unix/syscall-template.S 

どのようなエラーが発生する可能性がありますか?

$ uname -a 
Linux kiosk2 2.6.32-34-generiC#77-Ubuntu SMP Tue Sep 13 19:39:17 UTC 2011 x86_64 GNU/Linux 
+0

問題は何ですか? – Tshepang

答えて

26

それはコードを見ずに言うことは不可能ですが、選択ベースのループは〜100%のCPU使用率で回転を開始するとき、あなたが見てselect()に語ったソケットの1つ以上は既成あるため、多くの場合、それはですread(および/またはwrite-ready)のために、select()がすぐにブロックするのではなく戻りますが、そのコードは実際にはそのソケットのデータをrecv()(またはsend())に無視します。読み書きに失敗した後、イベントループはselect()を再度呼び出すことによってスリープ状態に戻りますが、もちろんソケットのデータ(または書き込み可能な場合のバッファスペース)はまだ処理待ちです、そうselect()戻ってすぐに再び、バグのあるコードが再び、そして周りの読み取りを行うために(またはwrite())を無視し、周りの私たちは、最高速度で行く:)

別の可能性は、あなたがselect()にタイムアウト値を渡しているということでしょうこれは0またはゼロに近い値になり、select()の各呼び出しの前にtimeval構造体を再初期化するのを忘れたときによく発生するソケットが準備が整っていなくても、非常に迅速に返るようになります(select())。 select()のいくつかの実装は、戻り前に変更するため、毎回timeval構造体を再初期化する必要があります。

私の提案は、select()への電話の直前と直後にいくつかのprintf(またはあなたの好きなもの)を置き、フォルトを再現しながらその出力を見ることです。これは、select()への1回の呼び出しの中でスピンが起こっているのか、何かがただちに何度も何度も何度も戻ってくることを示しています。

+3

質問にソースコードがないときに見た最高の回答の+1 –

関連する問題