函数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 结构体地址
1 typedef union epoll_data 2 { 3 void* ptr; 4 int fd; //对应监听的fd 5 uint32_t u32; 6 uint64_t u64; 7 } epoll_data_t; 8 9 struct epoll_event 10 { 11 uint32_t events; /* epoll事件 */ 12 epoll_data_t data; /* 用户数据 */ 13 };
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. 测试代码:
1 #include <errno.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <stdio.h> 5 6 #define MAXLINE 10 7 8 int main(int argc, char *argv[]) 9 { 10 int efd, i; 11 int pfd[2]; 12 pid_t pid; 13 char buf[MAXLINE],ch = 'a'; 14 pipe(pfd); 15 pid = fork(); 16 17 if (pid == 0) //子写 18 { 19 close(pfd[0]); //关闭读 20 while (1) 21 { 22 for (i = 0; i < MAXLINE / 2; i++) //aaaa 23 buf[i] = ch; 24 buf[i - 1] = ' '; 25 ch++; 26 27 for (; i < MACLINE; i++) //bbbb 28 buf[i] = ch; 29 buf[i - 1] = ' '; 30 ch++; 31 32 write(pdf[1], buf, sizeof(buf)); //aaaa bbbb 33 sleep(5); 34 } 35 close(pfd[1]); 36 } 37 else if (pid < 0) //父进程读 38 { 39 struct epoll_event; 40 struct epoll_event resevent[10]; 41 int res, len; 42 43 close(pfd[1]); //关闭写 44 efd = epoll_create(10); 45 46 //event.events = EPOLLIN | EPOLLET // ET边沿触发 47 even.events = EPOLLIN; // LT水平触发(默认) 48 event.data.fd = pfd[0]; 49 epoll_ctl(efd, EPOLL_CTL_ADD, pfd[0], &event); 50 51 while (1) 52 { 53 res = epoll_wait(efd, resevent, 10, -1); 54 printf("res %d ", res); 55 if (resevent[0].data.fd == pfd[0]) 56 { 57 len = read(pfd[0], buf, MACLINE/2); 58 write(STDOUT_FILENO, buf, len); 59 } 60 } 61 close(pfd[pfd[0]); 62 close(efd); 63 } 64 else 65 { 66 perror("fork"); 67 exit(-1); 68 } 69 return 0; 70 }
#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 buf[i] = ch; buf[i - 1] = ' '; ch++; for (; i < MACLINE; i++) //bbbb buf[i] = ch; buf[i - 1] = ' '; ch++; write(pdf[1], buf, sizeof(buf)); //aaaa bbbb 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 ", 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; }