作者信息:https://home.cnblogs.com/u/huangjiabobk

在Linux中,Epoll有哪些函数组成?

在Linux中,epoll主要由以下三个函数组成,这些函数共同实现了高效的I/O多路复用机制:

1. epoll_createepoll_create1
  • 功能:创建一个新的epoll实例,并返回一个文件描述符(FD),用于后续操作。

  • 函数原型

    int epoll_create(int size);
    int epoll_create1(int flags);
    
  • 参数

    • size:在旧版本中用于指定最大监听数量,现代内核已忽略此参数。
    • flags:用于设置epoll实例的属性,如EPOLL_CLOEXEC,表示在子进程中不会继承此文件描述符。
  • 返回值:成功时返回epoll文件描述符,失败时返回-1。

2. epoll_ctl
  • 功能:用于向epoll实例中添加、修改或删除文件描述符(FD)及其关注的事件。

  • 函数原型

    int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
    
  • 参数

    • epfd:由epoll_createepoll_create1创建的epoll文件描述符。
    • op:操作类型,可以是EPOLL_CTL_ADD(添加FD)、EPOLL_CTL_MOD(修改FD的事件)或EPOLL_CTL_DEL(删除FD)。
    • fd:需要操作的文件描述符。
    • event:指向epoll_event结构体的指针,用于指定FD关注的事件类型(如EPOLLINEPOLLOUT等)。
  • 返回值:成功时返回0,失败时返回-1。

3. epoll_wait
  • 功能:阻塞等待epoll实例中注册的事件发生,并返回就绪的文件描述符。

  • 函数原型

    int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
    
  • 参数

    • epfdepoll文件描述符。
    • events:用于存储就绪事件的数组。
    • maxeventsevents数组的最大容量。
    • timeout:超时时间(毫秒为单位),-1表示无限期等待。
  • 返回值:返回就绪事件的数量,失败时返回-1。

4. 示例代码

以下是一个简单的epoll服务器示例,监听一个TCP端口并处理客户端连接:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <fcntl.h>

#define MAX_EVENTS 10
#define PORT 8080

int main() {
    int server_fd, epoll_fd;
    struct sockaddr_in server_addr;
    struct epoll_event event, events[MAX_EVENTS];

    // 创建TCP服务器
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(PORT);
    bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    listen(server_fd, SOMAXCONN);

    // 创建epoll实例
    epoll_fd = epoll_create1(0);
    event.events = EPOLLIN;
    event.data.fd = server_fd;
    epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &event);

    printf("Server listening on port %d\n", PORT);
    while (1) {
        int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
        for (int i = 0; i < nfds; i++) {
            if (events[i].data.fd == server_fd) {
                // 接受新连接
                int client_fd = accept(server_fd, NULL, NULL);
                event.events = EPOLLIN | EPOLLET;
                event.data.fd = client_fd;
                epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &event);
                printf("New client connected: %d\n", client_fd);
            } else {
                // 处理客户端数据
                int client_fd = events[i].data.fd;
                char buffer[1024];
                ssize_t bytes_read = read(client_fd, buffer, sizeof(buffer));
                if (bytes_read <= 0) {
                    close(client_fd);
                    printf("Client disconnected: %d\n", client_fd);
                } else {
                    printf("Received from client %d: %s\n", client_fd, buffer);
                }
            }
        }
    }
    close(server_fd);
    close(epoll_fd);
    return 0;
}

综上所述,通过epoll_createepoll_ctlepoll_waitepoll能够高效地管理大量并发连接,特别适合高并发的网络服务器场景。

posted @ 2025-03-14 14:55  黄嘉波  阅读(35)  评论(0)    收藏  举报
版权声明:原创作品,谢绝转载!否则将追究法律责任。--作者 黄嘉波