函数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;
}

 

posted @ 2019-01-13 19:55  苏格拉底的落泪  阅读(410)  评论(0编辑  收藏  举报