用C++处理读缓冲区的更好方法

Better way to handle read buffer in C++

本文关键字:更好 方法 缓冲区 C++ 处理      更新时间:2023-10-16

我正在使用epoll操作linux服务器。我有这个代码来读取缓冲区

 int str_len = read(m_events[i].data.fd, buf, BUF_SIZE);
 if (str_len == 0) {
      if (!removeClient(m_events[i].data.fd))
          break;
      close(m_events[i].data.fd);
 } else {
      char *pdata = buf;
      pushWork(pdata);
 }

buf是这样声明的

buf[BUF_SIZE]

pushWork函数声明如下

 pushWork(char *pdata){
     push pdata to the thread pool's queue 
 }

首先,我认为char*pdatea=buf有一个问题,因为它只指向缓冲区,每当有新数据进入时,缓冲区就会被覆盖。那么我需要memcpy吗?

此外,在c++中还有其他很好的方法来处理这个问题吗?这段代码是一种c风格,我认为我有一种更好的方法来用c++实现这一点。

有其他好的处理方法吗这是c++中的吗?这个代码有点像c风格我想我有更好的方式在c++中执行此操作

就像我在你之前的一个问题中建议的那样,Boost。Asio库是事实上的C++网络库。如果你正在编写一个C++网络应用程序,我强烈建议你花一些时间阅读并研究这些例子。

这种方式很糟糕,因为你只有一个buf,这意味着你一次只能有一个线程在处理它,所以你没有像应该使用的那样使用线程。

你可以做的是malloc()一个缓冲区,将负载复制到malloc的缓冲区并将其传递给线程,然后让线程在使用完缓冲区时释放该缓冲区。只要确保释放它,否则就会出现内存泄漏。

示例代码:

char * p;
p = (char *)malloc(str_len+1);
memcpy(p, buf, str_len+1);
pushWork(p); //free p inside, after use.

您将需要执行memcpy(或类似的操作),除非您能够在pushWork()返回后永远不需要(buf)中的数据。如果您能够在pushWork(),OTOH中处理缓冲区的所有数据,则无需复制缓冲区。

另一种选择是,每次通过epoll循环时,提前从堆中分配一个缓冲区,并直接读取()到该缓冲区,而不是读取到堆栈上的缓冲区。。。这样,在事件循环进行到其他事情之后,动态分配的缓冲区仍然可以使用。请注意,这样做会为可能的内存泄漏或内存耗尽打开大门,因此您需要小心避免这些问题。

至于"C++方法",我相信有一些,但我不知道它们一定会改进你的程序。C方式运行良好,为什么要修复未损坏的东西?

(还有一点需要注意:如果您使用的是非阻塞I/O,那么read()有时会读取并返回少于BUF_SIZE字节的字节,在这种情况下,您需要逻辑来处理这种可能性。如果您使用的是阻塞I/O,OTOH,read()有时会阻塞很长一段时间(例如,如果客户端机器只发送了一半缓冲区就死了),这将阻塞您的epoll循环,并使其在几分钟内没有响应。这是一个更难处理的问题,这就是为什么我通常最终使用非阻塞I/O,即使这更难解决。