3

私は C で書かれたデーモン アプリケーションを持っており、現在、Solaris 10 マシンで既知の問題なしで実行しています。Linuxへの移植を進めています。最小限の変更を加える必要がありました。テスト中、すべてのテスト ケースに合格します。機能に問題はありません。ただし、Solaris マシンで「アイドル」状態のときの CPU 使用率を表示すると、約 .03% の CPU が使用されています。Red Hat Enterprise Linux 4.8 を実行している仮想マシンでは、同じプロセスが使用可能なすべての CPU (通常は 90% 以上の範囲) を使用します。

最初に考えたのは、イベント ループに何か問題があるに違いないということでした。while(1)イベント ループは、への呼び出しを伴う無限ループ ( )select()です。timeval は、timeval.tv_sec = 0およびtimeval.tv_usec = 1000. これは、プロセスが行っていることに対して十分に合理的と思われます。テストとして、私は 1 にぶつけましtimeval.tv_secた。それを行った後でも、同じ問題が発生しました。

Linux と Unix で select がどのように機能するかについて、私が見逃しているものはありますか? または、仮想マシンで実行されている OS とは異なる動作をしますか? それとも、私が完全に見逃している何かがあるのでしょうか?

もう 1 つ、使用されている vmware サーバーのバージョンがわかりません。とはいえ、約1ヶ月前に更新されたばかりです。

4

2 に答える 2

5

Linux は残り時間を select() 呼び出しの時間パラメーターに書き込むことで返すと思いますが、Solaris はそうではありません。つまり、POSIX 仕様を知らないプログラマーは、select の呼び出しの間に時間パラメーターをリセットしない可能性があります。

これにより、最初の呼び出しで 1000 usec タイムアウトが発生し、他のすべての呼び出しでは 0 usec タイムアウトが使用されます。

于 2010-03-12T20:12:41.070 に答える
1

Zan Lynx が言ったように、timeval は Linux の select によって変更されるため、各 select 呼び出しの前に正しい値を再割り当てする必要があります。また、ファイル記述子の一部が特定の状態にあるかどうかを確認することをお勧めします (ファイルの終わり、ピア接続のクローズなど)。移植により、戻り値の解析 (FD_ISSET など) に潜在的なバグが見られる可能性があります。数年前、選択駆動サイクルのポートで私にも起こりました。返された値を間違った方法で使用していたため、閉じられた fd が rd_set に追加されたため、選択が失敗しました。古いプラットフォームでは、誤った fd が maxfd よりも高い値を持つために使用されていたため、無視されていました。同じバグのため、プログラムは選択の失敗 (select() == -1) を認識せず、永久にループしました。

さよなら!

于 2010-03-12T20:30:08.300 に答える