c++ - FileServer 可以避免高 CPU 使用率吗?

标签 c++ linux sockets networking cpu-usage

我们有一个服务器应用程序,它将文件从 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),由 this post 表示。在我们的测试中,我们只保留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 使用率急剧上升,因为每个函数调用只会处理一两个数据包,但我们担心传输速度也会降低。那么有没有其他方法可以解决这个问题呢?

最佳答案

是的。 CPU 不应该做太多工作。你真正做的唯一一件事就是复制字节,and that is unnecessary .

关于c++ - FileServer 可以避免高 CPU 使用率吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17925037/

相关文章:

java - C语言如何为特定任务编写像多线程一样的Java?它可以作为 objective-c 来完成吗?

python - 验证域的脚本

python - 如何在Python中运行多线程进行多客户端套接字编程?

c++ - 使用 blitz++ 声明 3d 数组

c++ - 通过引用传递数组参数

C++ "cannot add two pointers",将硬编码字符串添加到 CString

regex - 像 "regexec"这样的正则表达式函数在 libc 版本 2.2.5 中是线程安全的吗?

linux - 用于查找该目录中保留过去 7 天内创建的文件的空间有多少的命令。不使用 `find`

javascript - 无法让 socket.io 在服务器上工作,同时在本地运行良好

c++ - 使用(float&)int可以进行类型修剪,(float const&)int可以像(float)int那样转换吗?