使用struct epoll_事件处理内存
我正在用C开发一个服务器,我有一个问题,关于如何处理使用struct epoll_事件处理内存,c,linux,epoll,C,Linux,Epoll,我正在用C开发一个服务器,我有一个问题,关于如何处理struct epoll\u事件的内存。我在一些在线示例中注意到,在进行epoll\u ctl调用时,会在堆栈上分配events参数,然后传递指针,如下所示: struct epoll_event ev; ev.events = EPOLLIN; epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev); 现在我们都知道当函数返回时,ev会发生什么。我的问题是:epoll库是在内部复制这些值,还是依赖于传
struct epoll\u事件的内存。我在一些在线示例中注意到,在进行epoll\u ctl
调用时,会在堆栈上分配events
参数,然后传递指针,如下所示:
struct epoll_event ev;
ev.events = EPOLLIN;
epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
现在我们都知道当函数返回时,ev
会发生什么。我的问题是:epoll库是在内部复制这些值,还是依赖于传递给堆分配的结构?上面的例子会完全破坏我的reactor实现吗?如果是这样,跟踪堆分配的epoll\u事件structs的最佳方法是什么
谢谢您的时间。一切都很好。epoll\u ctl
函数是一个简单的系统调用包装器,当函数返回时,系统调用将完全完成。不需要来自用户空间的进一步数据。该结构只是打包参数的一种方式。立即丢弃或重用您的epoll_事件结构绝对没有问题
内核将从epoll_事件结构中复制参数
这与使用以结构为参数的ioctl或以结构sockaddr_为参数的套接字操作(如bind)完全相同
内核获取了它所需要的,您可以立即释放它
你唯一需要担心的是“用户数据”,它只与你相关。内核将存储它,但您需要知道它在获取事件时的含义。epoll
是一组系统调用,而不是库。当您调用epoll
系统调用时,您进入内核,内核通常不相信这些用户模式缓冲区一定有效或保持不变,而是通过copy\u from\u user
等将其复制到内核内存中。因此,可以在堆栈上设置结构,将其地址传递给系统调用,然后在返回后丢弃它们。正如大家所说,struct epoll\u event*
参数指向的内存可以在epoll\u ctl()之后释放或重用
在中,我们看到内核复制了struct epoll_事件,这证实了我们所相信的
SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
struct epoll_event __user *, event)
{
struct epoll_event epds;
if (ep_op_has_event(op) &&
copy_from_user(&epds, event, sizeof(struct epoll_event)))
return -EFAULT;
return do_epoll_ctl(epfd, op, fd, &epds, false);
}
如果“我们都知道会发生什么”,那你为什么要问?当我说“我们都知道会发生什么”时,我的意思是当函数返回时,堆栈分配的内存被释放。谢谢。向上投票。但是,我会将Kerrek SB的答案标记为正确,因为他比您早一分钟回答。我希望此信息在手册页中,并且不需要往返访问。但是,我仍然想知道为什么参数不是struct epoll\u event const*
,而是没有const。