我有一个多线程服务器应用程序。该应用程序从套接字接收数据,然后处理这些数据,如解包,添加到数据队列等,功能如下。该函数被频繁调用。有一个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%。为什么?
[更新]
增加更多代码
[update2]
最奇怪的是我还写了另一个简单的数据接收服务器和客户端。服务器只是简单地从套接字接收数据然后丢弃它。两种类型的空间分配工作几乎相同,CPU 使用率没有太大差异。在有问题的多线程服务器应用程序中,我什至将进程堆栈大小重置为 30M,使用数组仍然会导致问题,但从堆中分配解决了它。我不知道为什么。
关于“sizeof(buffer)”,感谢您指出这一点,但我 100% 确定这不是问题,因为在我的应用程序中我不使用 sizeof(buffer),而是使用 ONE_MEGA (1024*1024) .
顺便说一句,尽管我不确定它是否有用,但还有一件事要提。将数组替换为较小的数组,例如 "char buffer[1024]; 也会显着降低 CPU 使用率。
[update3]
所有套接字都处于非阻塞模式。