我们有一个服务器应用程序,它将文件从 clientA 中继到 clientB、clientC、clientD 等。我们将这种文件中继称为任务。如果有很多任务正在执行,那么 CPU 使用率会非常非常高。
我想知道并发执行多个任务时这种高CPU使用率现象是否正常。有什么方法可以减少这种应用程序中的 CPU 使用率?
//pseudo code
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
**all fd are in non-blocking mode**
receive_data(fd);
}
}
}
void receive_data(int fd){
const int ONE_MEGA = 1024 * 1024;
char *buffer = new char[ONE_MEGA];
int readn = recv(fd, buffer, ONE_MEGA, 0);
//handle the data: many steps
char* DataToProcess = buffer;
int LenToProcess = readn;
while(LenToProcess > 0){
1. scan the data to find the packet header
2. get the length from the packet then perform checksum
function which will scan every character of the packet
to get a checksum value.
3. if the packet is valid then add the packet to data queue.
Move the buffer pointer and process the remaining data.
......
LenToProcess -= DataProcessed;
DataToProcess += DataProcessed;
};
}
如您所见,receive_data() 中的所有三个步骤都是 cpu 密集型操作。有什么方法可以在此类操作中尽可能减少 CPU 使用率(除了这种方式:设置一个非常小的缓冲区大小,例如“char buffer[1024]”)?
这里的问题是我们的应用程序将与同一台机器上的另一个服务器应用程序一起运行,因此 FileRelayer 应用程序不能消耗过多的 cpu,否则其他服务器应用程序将无法正常工作--!
[更新]
以下是有关该应用程序的一些信息:
A. 在这个 FileServer 多线程服务器应用程序中大约有 70 个线程,但其中只有一个用于从所有套接字接收数据。
B. 所有套接字都处于非阻塞模式,包括监听套接字。
C. 当应用程序从 4 个客户端(4 个套接字)接收 4 个 200 Mega 的文件时,发现 CPU 使用率很高(80% - 90%)。
关于问题:
我们将整个接收流分为两个主要部分,我们称它们为FlowA和FlowB。FlowA 只接收来自套接字的数据。FlowB代表receive_data()中处理数据的部分,如数据包切片等。我们发现FlowA和FlowB分别会导致CPU使用率高。
1)FlowA:从堆栈分配的大数组(1 Mega),由这篇文章描述。在我们的测试中,我们只留下 FlowA(从套接字接收数据后丢弃),发现 CPU 使用率长时间保持在 80-90% 的高位。并且将“char Buffer[ONE_MEGA]”替换为“char *buffer = new char[ONE_MEGA]”,CPU 使用率降低到 14%。
2) FlowA + FlowB:我们解决FlowA的问题后,发现整个流程(FlowA + FlowB)的CPU使用率仍然高达80%,但这次有所波动。
将接收缓冲区设置为非常小的缓冲区,例如 char buffer[1024] 会大大降低 cpu 使用率,因为每个函数调用它只会处理一两个数据包,但我们担心传输速度也会降低。那么有没有其他方法可以解决这个问题呢?</p>