如何使用 epoll(void* event.data.ptr) 管理 Connection 的生命周期
How to manage the life cycle of Connection using epoll(void* event.data.ptr)
我正在使用C++实现epoll
。 我想学习nginx使用(void*) event.data.ptr
与Connection
相关联。Connection
是一个聪明的指针。但是在void*
之间,我需要将智能指针转换为原始指针。
在转换和获取过程中,引用的数量没有增加,这显然是程序会崩溃的。 所以我不使用智能指针。
我使用new
和delete
.但它太可怕了。
如何管理Connection
的生命周期?
int nfds = epoll_wait(epollfd, event_list, 100, -1);
for (int n = 0; n < nfds; ++n) {
auto event = event_list[n];
auto revents = event.events;
if (revents & EPOLLIN) {
if (event.data.fd == listen_fd_) {
int fd = handleAccept(listen_fd_);
auto conn_ptr = std::make_shared<Connection>(fd, connections_manager_);
//connecions_manager_ is std::set<std::shared_ptr<Connection>>
//it use start, stop and stop_all manage Connection.
connections_manager_.start(conn_ptr);
struct epoll_event ev;
ev.events = EPOLLIN | EPOLLET;
ev.data.ptr = static_cast<void*>(conn_ptr.get());
if (epoll_ctl(event_.getEpollFd(), EPOLL_CTL_ADD, fd, &ev) == -1) {
std::cout << "epoll_ctl failed. fd is " << fd << 'n';
perror("epoll_ctl: fd_");
exit(EXIT_FAILURE);
}
continue;
}
auto conn = static_cast<Connection *>(event.data.ptr);
conn->start();
}
}
以下是您可能想要实现的一般想法:
- 保留您创建的所有
Connection
对象的列表。一个简单的C式数组就可以了,但你可以检查使用std::vector
、std::map
或std::unordered_map
来记Connection
对象的可能性。 - 每当创建新
Connection
时,您都会先将其添加到列表中,然后再将其添加到epoll
池中。我建议为此add()
单独的方法。 - 同样,在关闭
Connection
(从主机或客户端)时,需要将其从池中删除epoll
。但是,它将在您的连接列表中。您可能需要一个标志,例如isClosed
并将其设置为true
以关闭连接。不要删除epoll
主事件循环中的Connection
对象。此外,在关闭连接之前,您需要一些东西来确定是否还有一些数据要发送。客户端可能正在等待从服务器接收数据。 - 对于这些已关闭连接的垃圾回收,您可以使用具有固定时间间隔的单独线程来浏览列表并删除已关闭的连接。
一般来说,你可能需要一些包装方法来分解你的操作,wait
、listen
、add
、remove
等。它会更容易管理。此外,您可能有专用于读/写操作的单独线程池。在主事件循环中接受连接就好了。
希望对您有所帮助!
如果您想进一步讨论,请告诉我。
相关文章:
- 当vector是tje全局变量时,c++中vector的内存管理
- 如何维护资源管理器项目视图中当前可见的项目列表
- 如何在GTK程序运行时禁用屏幕保护程序/电源管理/屏幕消隐
- 资源管理设计模式
- 使用"Task"函数指针队列定义作业管理器
- 实现动态插件管理器
- Alt+Enter 在 Win32 应用中,管理大小调整和分辨率
- libcurl 和 DNS ttl 中的内部连接管理
- 当分配一个字符串值并稍后通过分配另一个值进行更改时C++如何管理内存?
- 在C++管理一家中国.txt
- 编译器资源管理器和 GCC 具有不同的输出
- 我们可以通过 IPC 传递具有动态管理成员的类对象吗?
- 使用 Git 处理 C++ Visual Studio 2019 解决方案的外部依赖项源代码管理的最佳方法是什么?
- Q没有管理权限的 exe 无法启动维护工具
- QT:管理来自 QNetworkReply 的回复
- 使用 std::vector<double> 访问由 std::unique_ptr<double[2] 管理的数据>
- 读取 TCP 标头并使用RAW_SOCKET管理 TCP 连接
- Windows 资源管理器中的图标在使用 resource.rc 时显示 2 个不同的图标
- 管理字符串文本的最佳做法
- 如何使用 epoll(void* event.data.ptr) 管理 Connection 的生命周期