用C++处理读缓冲区的更好方法
Better way to handle read buffer in C++
我正在使用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,即使这更难解决。
- 初始化具有非默认构造函数的std::数组项的更好方法
- Protobuf中重复字段的问题.使用重复字段进行序列化/反序列化的更好方法是什么?
- 编写按初始值循环的循环的更好方法是什么
- 用 c++ 为游戏制作"bullet"的更好方法?
- 在CMakeLists中包含目录的更好方法.txt
- 将QDomDocument数据用作文本的更好方法
- C++ - 创建具有相同字符的特定大小的以 null 结尾的 c 样式字符串的更好方法
- 在 sqlite3 中批量插入的更好方法C++
- 设计许多单例代码结构的更好方法
- 使用继承的类模板避免公共成员不可见和源代码膨胀/重复的更好方法
- 在初始化列表中初始化数组的更好方法
- 将对象从一个 std::d eque 移动到另一个的更好方法
- 请告诉我在巴泽尔拥有多平台工作空间的更好方法
- 构造具有大量数据的对象的更好方法(C++)
- 从2D矢量中找出最小尺寸的向量元素的更好方法
- 在C++中创建不可变对象的更好方法
- 在构造函数中组织初始值设定项列表的更好方法
- std::copy with return values - 防止"expression: string iterators incompatible"的更好方法?
- 删除数组成员的更好方法是什么?
- 在C 中操作数据的更好方法是什么