マルチスレッド サーバー アプリケーションがあります。このアプリケーションは、ソケットからデータを受け取り、パッケージのアンパック、データ キューへの追加など、これらのデータを処理します。機能は次のとおりです。この関数は頻繁に呼び出されます。select ステートメントがあり、データがあることがわかった場合は、この関数を呼び出して受信します):
//the main function used to receive
//file data from clients
void service(void){
while(1){
....
struct timeval timeout;
timeout.tv_sec = 3;
...
ret = select(maxFd+1, &read_set, NULL, NULL, &timeout);
if (ret > 0){
//get socket from SocketsMap
//if fd in SocketsMap and its being set
//then receive data from the socket
receive_data(fd);
}
}
}
void receive_data(int fd){
const int ONE_MEGA = 1024 * 1024;
//char *buffer = new char[ONE_MEGA]; consumes much less CPU
char buffer[ONE_MEGA]; // cause high CPU
int readn = recv(fd, buffer, ONE_MEGA, 0);
//handle the data
}
上記は CPU を消費しすぎることがわかりました。通常は 80% から 90% ですが、代わりにヒープからバッファーを作成すると、CPU は 14% しかありません。なんで?
[更新]
コードを追加
[更新 2]
最も奇妙なことは、別の単純なデータ受信サーバーとクライアントも作成したことです。サーバーは、ソケットからデータを受信して破棄するだけです。どちらのタイプのスペース割り当てもほぼ同じように機能し、CPU 使用率に大きな違いはありません。問題のあるマルチスレッド サーバー アプリケーションでは、プロセス スタック サイズを 30M にリセットしても、配列を使用すると問題が発生しますが、ヒープから割り当てることで解決します。どうしてか分かりません。
「sizeof(buffer)」については、ご指摘ありがとうございます。ただし、私のアプリケーションでは sizeof(buffer) を使用せず、代わりに ONE_MEGA (1024*1024) を使用しているため、問題ではないことは 100% 確信しています。 .
ところで、役に立つかどうかはわかりませんが、もう1つ言及する必要があります。配列を「char buffer[1024];」などの小さい配列に置き換えると、CPU 使用率が大幅に低下します。
[update3]
すべてのソケットがノンブロッキング モードです。