在Linux中,Epoll有哪些函数组成?
在Linux中,epoll
主要由以下三个函数组成,这些函数共同实现了高效的I/O多路复用机制:
1. epoll_create
或 epoll_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_create
或epoll_create1
创建的epoll
文件描述符。op
:操作类型,可以是EPOLL_CTL_ADD
(添加FD)、EPOLL_CTL_MOD
(修改FD的事件)或EPOLL_CTL_DEL
(删除FD)。fd
:需要操作的文件描述符。event
:指向epoll_event
结构体的指针,用于指定FD关注的事件类型(如EPOLLIN
、EPOLLOUT
等)。
-
返回值:成功时返回0,失败时返回-1。
3. epoll_wait
-
功能:阻塞等待
epoll
实例中注册的事件发生,并返回就绪的文件描述符。 -
函数原型:
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
-
参数:
epfd
:epoll
文件描述符。events
:用于存储就绪事件的数组。maxevents
:events
数组的最大容量。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_create
、epoll_ctl
和epoll_wait
,epoll
能够高效地管理大量并发连接,特别适合高并发的网络服务器场景。