• 【linux】操作系统的事件通知机制eventfd


    eventfd,是操作系统提供的事件通知机制,详情查看eventfd
    通过文件使用的形式,让俩个模块之间可以有交互,在一定程度上可以使用在进程间通信。
    时间机制是一种典型的生产和消费的模式,对于eventfd,有俩种主要的使用方式。

    • 纯通知模式
    • 类似信号模式(打开eventfd的时候加上EFD_SEMAPHORE)
      俩种的差别是,纯通知模式无论你write几次,最后read的时候,事件就里面清0;但是你读取的值是之前累加的值,因为它是一个counter。
      信号模式就是,你每次read,都是read一个信号出来。之前写入几次,你就可以read几次。

    read(2)
    Each successful read(2) returns an 8-byte integer. A
    read(2) fails with the error EINVAL if the size of the
    supplied buffer is less than 8 bytes.
    The semantics of read(2) depend on whether the eventfd
    counter currently has a nonzero value and whether the
    EFD_SEMAPHORE flag was specified when creating the eventfd
    file descriptor:
    1、If EFD_SEMAPHORE was not specified and the eventfd
    counter has a nonzero value, then a read(2) returns 8
    bytes containing that value, and the counter’s value is
    reset to zero.
    2、If EFD_SEMAPHORE was specified and the eventfd counter
    has a nonzero value, then a read(2) returns 8 bytes
    containing the value 1, and the counter’s value is
    decremented by 1.
    3、If the eventfd counter is zero at the time of the call
    to read(2), then the call either blocks until the
    counter becomes nonzero (at which time, the read(2)
    proceeds as described above) or fails with the error
    EAGAIN if the file descriptor has been made
    nonblocking.

    可以简单模拟下俩种的差别,代码还是很简单的。

    #include <sys/eventfd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #include <iostream> 
    
    int _event_fd;
    int openEventFd() {
        _event_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC | EFD_SEMAPHORE);
    }
    
    int testWriteEventFd() {
        uint64_t val = 1;
        size_t n = write(_event_fd, &val, sizeof(val));
        if (n != sizeof(n)) {
            cerr << "write event_fd failed!!!" << endl;
            return -1;
        }
        return 0;
    }
    
    int testReadEventFd() {
        uint64_t val = 1;
        size_t n = read(_event_fd, &val, sizeof(val));
        if (errno == EAGAIN) {
            return 0;
        }
    
        if (n != sizeof(n)) {
            cerr << "read event_fd failed!!!" << endl;
            return -1;
        }
    
        cout << "read " << val << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
  • 相关阅读:
    c++征途 ---- 类与对象 --- 继承
    git使用介绍
    STM32的hal库中,后缀带ex和不带的有什么区别
    弱引用回调引发的坑
    计算机网络学习笔记(5.传输层 6.应用层)
    JAVA计算机毕业设计消防网站(附源码、数据库)
    Leetcode 541:反转字符串II
    Windows10关闭系统自动更新
    5G网络入门基础--5G网络的架构与基本原理
    ebay卖家开店如何做到稳定出单?自养号测评对eBay卖家有什么优势?
  • 原文地址:https://blog.csdn.net/s120922718/article/details/125604066