eventfd(三)

1. 测试代码: 

//https://www.jianshu.com/p/d7ebac8dc9f8
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <pthread.h>
#include <sys/eventfd.h>
#include <sys/epoll.h>

int event_fd = -1;

void *read_thread(void *dummy)
{
    uint64_t inc = 1;
    int ret = 0;
    int i = 0;
    for (; i < 2; i++) 
    {
        ret = write(event_fd, &inc, sizeof(uint64_t));
        if (ret < 0) 
        {
            perror("child thread write event_fd fail.");
        } 
        else 
        {
            printf("child thread completed write %llu (0x%llx) to event_fd\n", (unsigned long long) inc, (unsigned long long) inc);
        }
        sleep(4);
    }
}

int main(int argc, char *argv[])
{
    int ret = 0;
    pthread_t pid = 0;

    event_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
    if (event_fd < 0) 
    {
        perror("event_fd create fail.");
    }

    ret = pthread_create(&pid, NULL, read_thread, NULL);
    if (ret < 0) 
    {
        perror("pthread create fail.");
    }

    uint64_t counter;
    int epoll_fd = -1;
    struct epoll_event events[16];
    if (event_fd < 0)
    {
        printf("event_fd not inited.\n");
    }

    epoll_fd = epoll_create(8);
    if (epoll_fd < 0)
    {
        perror("epoll_create fail:");
    }

    struct epoll_event read_event;
    read_event.events = EPOLLIN;
    read_event.data.fd = event_fd;
    ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, event_fd, &read_event);
    if (ret < 0) 
    {
        perror("epoll_ctl failed:");
    }

    while (1) 
    {
        printf("main thread epoll is waiting......\n");
        ret = epoll_wait(epoll_fd, events, 16, 2000);
        printf("main thread epoll_wait return ret : %d\n", ret);
        if (ret > 0) 
        {
            int i = 0;
            for (; i < ret; i++) 
            {
                int fd = events[i].data.fd;
                if (fd == event_fd) 
                {
                    uint32_t epollEvents = events[i].events;
                    if (epollEvents & EPOLLIN) 
                    {
                        ret = read(event_fd, &counter, sizeof(uint64_t));
                        if (ret < 0) 
                        {
                            printf("main thread read fail\n");
                        } 
                        else 
                        {
                            printf("main thread read %llu (0x%llx) from event_fd\n", (unsigned long long) counter, (unsigned long long) counter);
                        }
                    } 
                    else 
                    {
                        printf("main thread unexpected epoll events on event_fd\n");
                    }
                }
            }
        } 
        else if (ret == 0) 
        {
            printf("main thread epoll_wait timed out. continue epoll\n");
        } 
        else 
        {
            perror("main thread epoll_wait error.");
        }
    }
}

输出结果:

wufan@Frank-Linux:~/Linux/test$ ./epoll_eventfd 
main thread epoll is waiting...... // main 线程阻塞在读端
child thread completed write 1 (0x1) to event_fd // 第一次写入后阻塞 4 秒
main thread epoll_wait return ret : 1 // 第一次写完后,立即唤醒 main 线程去进行读操作
main thread read 1 (0x1) from event_fd // main 线程读到了数据
main thread epoll is waiting...... // main 线程阻塞又在读端,超时时间为 2 秒
main thread epoll_wait return ret : 0 // main 线程阻塞等待时间到,返回
main thread epoll_wait timed out. continue epoll
main thread epoll is waiting...... // main 线程阻塞又在读端,超时时间为 2 秒
child thread completed write 1 (0x1) to event_fd // // 第二次写入后阻塞 4 秒
main thread epoll_wait return ret : 1 // 第二次写完后,立即唤醒 main 线程去进行读操作
main thread read 1 (0x1) from event_fd // main 线程读到了数据
main thread epoll is waiting...... // main 线程阻塞又在读端,超时时间为 2 秒
main thread epoll_wait return ret : 0 // main 线程阻塞等待时间到,返回
main thread epoll_wait timed out. continue epoll
main thread epoll is waiting...... // main 线程阻塞又在读端,超时时间为 2 秒
只要没有写入数据,就会在这个死循环中阻塞 -> 超时 -> 阻塞...

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值