我正在使用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();
}
}
答案 0 :(得分:0)
以下是您可能希望实施的一般概念:
Connection
个对象的列表。可以使用简单的C风格数组,但您可以检查使用std::vector
,std::map
或std::unordered_map
进行Connection
对象簿记的可能性。Connection
时,都会将其添加到列表中,然后再将其添加到epoll
池中。我建议使用单独的方法add()
。Connection
(来自主机或客户端)时,您需要从epoll
池中删除它。但是,它会出现在您的连接列表中。你可能需要一个标志,例如isClosed
并为true
设置已关闭的连接。不要删除Connection
主事件循环中的epoll
个对象。此外,您还需要一些东西来确定是否有一些数据需要在关闭您身边的连接之前发送。客户端可能正在等待从服务器接收数据。通常,您可能需要一些wait
,listen
,add
,remove
等的包装方法来分解您的操作。它更容易管理。此外,您可能有专门用于读/写操作的单独线程池。接受主事件循环中的连接就好了。
希望有所帮助! 如果您想进一步讨论,请告诉我。