函数epoll
函数epoll
1. 函数epoll_creat: 该函数生成一个epoll专用的文件描述符:
int epoll_creae(int size);
参数:
- size:epoll上能关注的最大描述符数
2. epoll_ctl:用于控制某个epoll文件描述符事件,可以注册、修改、删除:
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
参数:
1. efd:epoll_create函数的返回值
2. op:对该监听红黑树所做的操作
- EPOLL_CTL_ADD:添加新的fd到epfd中
- EPOLL_CTL_MOD:修改fd在监听红黑树的监听事件
- EPOLL_CTL_DE:将一个fd从监听红黑树摘下
3. fd:待监听的fd
4. event:本质struct epoll_event 结构体地址
typedef union epoll_data
{
void* ptr;
int fd; //对应监听的fd
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event
{
uint32_t events; /* epoll事件 */
epoll_data_t data; /* 用户数据 */
};
3. 等待IO事件发生 - 可以设置阻塞的函数
1 int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
参数:
- efds:epoll_create函数的返回值
- events:传出参数【数组】满足监听条件的哪些fd结构体
- maxevents:数组元素的总个数(1024) struct epoll_events [1024]:
- timeout:
- ET:边缘触发只有数据到来才触发,不管缓冲区是否还有数据(缓冲区剩余未读尽的数据的数据不会导致epoll_wait返回。新的时间满足,才会触发)
- LT:水平触发 ---默认采用模式(缓冲区剩余未读尽的数据会导致epoll_wait返回。)
1. 测试代码:
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define MAXLINE 10
int main(int argc, char *argv[])
{
int efd, i;
int pfd[2];
pid_t pid;
char buf[MAXLINE],ch = 'a';
pipe(pfd);
pid = fork();
if (pid == 0) //子写
{
close(pfd[0]); //关闭读
while (1)
{
for (i = 0; i < MAXLINE / 2; i++) //aaaa\n
buf[i] = ch;
buf[i - 1] = '\n';
ch++;
for (; i < MACLINE; i++) //bbbb\n
buf[i] = ch;
buf[i - 1] = '\n';
ch++;
write(pdf[1], buf, sizeof(buf)); //aaaa\nbbbb\n
sleep(5);
}
close(pfd[1]);
}
else if (pid < 0) //父进程读
{
struct epoll_event;
struct epoll_event resevent[10];
int res, len;
close(pfd[1]); //关闭写
efd = epoll_create(10);
//event.events = EPOLLIN | EPOLLET // ET边沿触发
even.events = EPOLLIN; // LT水平触发(默认)
event.data.fd = pfd[0];
epoll_ctl(efd, EPOLL_CTL_ADD, pfd[0], &event);
while (1)
{
res = epoll_wait(efd, resevent, 10, -1);
printf("res %d\n", res);
if (resevent[0].data.fd == pfd[0])
{
len = read(pfd[0], buf, MACLINE/2);
write(STDOUT_FILENO, buf, len);
}
}
close(pfd[pfd[0]);
close(efd);
}
else
{
perror("fork");
exit(-1);
}
return 0;
}