几个例子,看懂poll和epoll

筅森魡賤 提交于 2019-12-07 15:39:59

1. poll的例子

#include <stdio.h>
#include <sys/eventfd.h>
#include <poll.h>

int main()
{
    uint64_t value = 2;
    int event_fd = eventfd(0, EFD_NONBLOCK);
    struct pollfd pfd;
    int status = 0;
    uint64_t check_value = 0;

    printf("event_fd=%d\n", event_fd);
    write(event_fd, &value, sizeof(value));
    write(event_fd, &value, sizeof(value));
    write(event_fd, &value, sizeof(value));
    
    read(event_fd, &check_value, sizeof(check_value));
    printf("read, value=%ld\n", check_value);

    int ret = fork();
    if (ret < 0)
    {
        printf("fork error\n");
    }

    if (ret == 0)
    {
        pfd.fd = event_fd;
            pfd.events = POLLIN;
        printf("__FILE: %s, __LINE: %d\n", __FILE__, __LINE__);
         
        ret = poll(&pfd, 1, -1);
        printf("__FILE: %s, __LINE: %d, ret: %d, pfd.revents: %d\n", __FILE__, __LINE__, ret, pfd.revents);
        ret = poll(&pfd, 1, -1);
        printf("__FILE: %s, __LINE: %d, ret: %d, pfd.revents: %d\n", __FILE__, __LINE__, ret, pfd.revents);
        ret = poll(&pfd, 1, -1);
        printf("__FILE: %s, __LINE: %d, ret: %d, pfd.revents: %d\n", __FILE__, __LINE__, ret, pfd.revents);
        ret = poll(&pfd, 1, -1);
        printf("__FILE: %s, __LINE: %d, ret: %d, pfd.revents: %d\n", __FILE__, __LINE__, ret, pfd.revents);
        return 0;
    }
    
    sleep(3);
    write(event_fd, &value, sizeof(value));
    waitpid(ret, &status, 0);    

    return 0;
}
 

数据结果为:
event_fd=3
read, value=6
__FILE: testfd.c, __LINE: 31:
__FILE: testfd.c, __LINE: 34, ret: 1, pfd.revents: 1
__FILE: testfd.c, __LINE: 36, ret: 1, pfd.revents: 1
__FILE: testfd.c, __LINE: 38, ret: 1, pfd.revents: 1
__FILE: testfd.c, __LINE: 40, ret: 1, pfd.revents: 1
 

2. epoll的例子

边缘触发例1:

#include <stdio.h>
#include <sys/eventfd.h>
#include <sys/epoll.h>
#include <memory.h>

int main()
{
    uint64_t value = 2;
    int event_fd = eventfd(0, 0);

    int i = 0;        
    int status = 0;
    uint64_t check_value = 0;

    /* epoll */
    int epfd = 0;
    struct epoll_event epevent[1], poolevent;
    printf("event_fd=%d\n", event_fd);

    int ret = fork();
    if (ret < 0)
    {
        printf("fork error\n");
        return(1);
    }

    if (ret == 0)
    {
        epfd = epoll_create(1);
        if (epfd == -1) {
            printf("\nepoll_create, failed\n");
            return -1;
        }    

        poolevent.events = EPOLLIN | EPOLLET;
        poolevent.data.fd = event_fd;


        sleep(10);        
        ret = epoll_ctl(epfd, EPOLL_CTL_ADD, event_fd, &poolevent);
        if (ret != 0)
        {
            printf("\nepoll_ctl, failed\n");
            close(epfd);
            return -1;
        }

        for(i = 0; i < 2; i++) 
        {
            printf("Child: wait events ... times: %d\n", i);
            epoll_wait(epfd, epevent, 1, -1); // here to monitor only 1 event(epevent), so the third parameter is 1
            if(!(epevent[0].events & EPOLLIN))
            {
                /* An error has occured on this fd, or the child is not
                   ready for reading (why were we notified then?) */
                fprintf (stderr, "epoll error epevents is %d\n", epevent[0].events);
                close (epevent[0].data.fd);
                return(1);
            } else if (event_fd == epevent[0].data.fd) {
                printf("Child: Got an event\n");
            } else
                printf("Child: No event first time\n");

        }    
        close(epfd);
        printf("Child: exit\n");
        return 0;
    }
    //sleep(10);
    printf("Father: write\n");
    write(event_fd, &value, sizeof(value));
    
    //sleep(10);
    printf("Father: write again\n");
    write(event_fd, &value, sizeof(value));
    //sleep(10);
    //*/
    printf("Father: wait child exit\n");
    
    waitpid(ret, &status, 0);    

    close(event_fd);
    return 0;
}

数据结果为:
event_fd=3
Father: write
Father: write again
Father: wait child exit
Child: wait events ... times: 0
Child: Got an event
Child: wait events ... times: 1
然后程序一直挂住不退出

边缘触发例2

#include <stdio.h>
#include <sys/eventfd.h>
#include <sys/epoll.h>
#include <memory.h>

int main()
{
    uint64_t value = 2;
    int event_fd = eventfd(0, 0);

    int i = 0;        
    int status = 0;
    uint64_t check_value = 0;

    /* epoll */
    int epfd = 0;
    struct epoll_event epevent[1], poolevent;
    printf("event_fd=%d\n", event_fd);

    int ret = fork();
    if (ret < 0)
    {
        printf("fork error\n");
        return(1);
    }

    if (ret == 0)
    {
        epfd = epoll_create(1);
        if (epfd == -1) {
            printf("\nepoll_create, failed\n");
            return -1;
        }    

        poolevent.events = EPOLLIN | EPOLLET;
        poolevent.data.fd = event_fd;


        //sleep(10);        
        ret = epoll_ctl(epfd, EPOLL_CTL_ADD, event_fd, &poolevent);
        if (ret != 0)
        {
            printf("\nepoll_ctl, failed\n");
            close(epfd);
            return -1;
        }

        for(i = 0; i < 2; i++) 
        {
            printf("Child: wait events ... times: %d\n", i);
            epoll_wait(epfd, epevent, 1, -1); // here to monitor only 1 event(epevent), so the third parameter is 1
            if(!(epevent[0].events & EPOLLIN))
            {
                /* An error has occured on this fd, or the child is not
                   ready for reading (why were we notified then?) */
                fprintf (stderr, "epoll error epevents is %d\n", epevent[0].events);
                close (epevent[0].data.fd);
                return(1);
            } else if (event_fd == epevent[0].data.fd) {
                printf("Child: Got an event\n");
            } else
                printf("Child: No event first time\n");

        }    
    
        close(epfd);
        printf("Child: exit\n");
        return 0;
    }
    sleep(10);
    printf("Father: write\n");
    write(event_fd, &value, sizeof(value));
    
    sleep(10);
    printf("Father: write again\n");
    write(event_fd, &value, sizeof(value));
    //sleep(10);
    //*/
    printf("Father: wait child exit\n");
    
    waitpid(ret, &status, 0);    

    close(event_fd);
    return 0;
}

输出结果为:

event_fd=3
Child: wait events ... times: 0
Father: write
Child: Got an event
Child: wait events ... times: 1
Father: write again
Father: wait child exit
Child: Got an event
Child: exit
 

水平触发例1:

#include <stdio.h>
#include <sys/eventfd.h>
#include <sys/epoll.h>
#include <memory.h>

int main()
{
    uint64_t value = 2;
    int event_fd = eventfd(0, 0);

    int i = 0;        
    int status = 0;
    uint64_t check_value = 0;

    /* epoll */
    int epfd = 0;
    struct epoll_event epevent[1], poolevent;
    printf("event_fd=%d\n", event_fd);

    int ret = fork();
    if (ret < 0)
    {
        printf("fork error\n");
        return(1);
    }

    if (ret == 0)
    {
        epfd = epoll_create(1);
        if (epfd == -1) {
            printf("\nepoll_create, failed\n");
            return -1;
        }    

        poolevent.events = EPOLLIN ;
        poolevent.data.fd = event_fd;


        sleep(10);        
        ret = epoll_ctl(epfd, EPOLL_CTL_ADD, event_fd, &poolevent);
        if (ret != 0)
        {
            printf("\nepoll_ctl, failed\n");
            close(epfd);
            return -1;
        }

        for(i = 0; i < 2; i++) 
        {
            printf("Child: wait events ... times: %d\n", i);
            epoll_wait(epfd, epevent, 1, -1); // here to monitor only 1 event(epevent), so the third parameter is 1
            if(!(epevent[0].events & EPOLLIN))
            {
                /* An error has occured on this fd, or the child is not
                   ready for reading (why were we notified then?) */
                fprintf (stderr, "epoll error epevents is %d\n", epevent[0].events);
                close (epevent[0].data.fd);
                return(1);
            } else if (event_fd == epevent[0].data.fd) {
                printf("Child: Got an event\n");
            } else
                printf("Child: No event first time\n");

        }    
    
        close(epfd);
        printf("Child: exit\n");
        return 0;
    }
    //sleep(10);
    printf("Father: write\n");
    write(event_fd, &value, sizeof(value));
    
    //sleep(10);
    printf("Father: write again\n");
    write(event_fd, &value, sizeof(value));
    //sleep(10);
    //*/
    printf("Father: wait child exit\n");
    
    waitpid(ret, &status, 0);    

    close(event_fd);
    return 0;
}


结果输出:
event_fd=3
Father: write
Father: write again
Father: wait child exit
Child: wait events ... times: 0
Child: Got an event
Child: wait events ... times: 1
Child: Got an event
Child: exit
 

水平触发例2:

#include <stdio.h>
#include <sys/eventfd.h>
#include <sys/epoll.h>
#include <memory.h>

int main()
{
    uint64_t value = 2;
    int event_fd = eventfd(0, 0);

    int i = 0;        
    int status = 0;
    uint64_t check_value = 0;

    /* epoll */
    int epfd = 0;
    struct epoll_event epevent[1], poolevent;
    printf("event_fd=%d\n", event_fd);

    int ret = fork();
    if (ret < 0)
    {
        printf("fork error\n");
        return(1);
    }

    if (ret == 0)
    {
        epfd = epoll_create(1);
        if (epfd == -1) {
            printf("\nepoll_create, failed\n");
            return -1;
        }    

        poolevent.events = EPOLLIN;
        poolevent.data.fd = event_fd;


        //sleep(10);        
        ret = epoll_ctl(epfd, EPOLL_CTL_ADD, event_fd, &poolevent);
        if (ret != 0)
        {
            printf("\nepoll_ctl, failed\n");
            close(epfd);
            return -1;
        }

        for(i = 0; i < 2; i++) 
        {
            printf("Child: wait events ... times: %d\n", i);
            epoll_wait(epfd, epevent, 1, -1); // here to monitor only 1 event(epevent), so the third parameter is 1
            if(!(epevent[0].events & EPOLLIN))
            {
                /* An error has occured on this fd, or the child is not
                   ready for reading (why were we notified then?) */
                fprintf (stderr, "epoll error epevents is %d\n", epevent[0].events);
                close (epevent[0].data.fd);
                return(1);
            } else if (event_fd == epevent[0].data.fd) {
                printf("Child: Got an event\n");
            } else
                printf("Child: No event first time\n");

        }    
    
        close(epfd);
        printf("Child: exit\n");
        return 0;
    }
    sleep(10);
    printf("Father: write\n");
    write(event_fd, &value, sizeof(value));
    
    sleep(10);
    printf("Father: write again\n");
    write(event_fd, &value, sizeof(value));
    //sleep(10);
    //*/
    printf("Father: wait child exit\n");
    
    waitpid(ret, &status, 0);    

    close(event_fd);
    return 0;
}
输出结果:
event_fd=3
Child: wait events ... times: 0
Father: write
Child: Got an event
Child: wait events ... times: 1
Child: Got an event
Child: exit
Father: write again
Father: wait child exit
 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!