linux eventfd事件通知 比信号量更好用

这篇具有很好参考价值的文章主要介绍了linux eventfd事件通知 比信号量更好用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  

 文章来源地址https://www.toymoban.com/news/detail-481122.html

  • 专栏内容:linux下并发编程
  • 个人主页:我的主页
  • 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

目录

前言

概述

原理简介

使用场景

接口说明

头文件

参数说明

代码演示

默认参数

信号量模式

结尾


 

前言

本专栏主要分享linux下并发编程相关知识,包括多进程,多线程,进程/线程间通信,并发同步控制,以及高并发下性能提升,请大家多多留言。


 

概述

eventfd 就是一个用于事件通知的fd。当然linux中,一切都可以做为文件来看待,所以就有fd。这样有一个好处管理统一,比如可以加入到epoll事件等待中。很多人可能没怎么用,但是用过的人都说:香 !

 

原理简介

eventfd 提供了一个进程/线程间通信的方式。

 

这个方式是载体是一个句柄,也就是fd,类型是eventfd,可以在/proc下查看fd时看到;

 

通过它可以传递事件信息,事件就是write次数累计,这个累计值用一个8字节整型值来记录,每次write时这个整型值自动会累计,它是由内核来维护,read时就会拿到累计值,并清零fd中的值。

 

当然这个eventfd,可以传入poll来监听,监听可读可写事件。

 

可写事件, eventfd的write是一直可以的,它可以不断累加,所以一直会是可写状态,所以可以不用理会可写事件。

可读事件,当eventfd的累计值为零时,为不可读状态,当大于零时,才可读。这样就提供了一种通知机制。

 

使用场景

适用于等待-通知的架构模式,类似于信号量的场景。

比如生产者准备好后,通知消费者;等待的消费者获取到通知后,进行消费;消费完后,消费者又开始等待。

 

那么,信号量也可以实现,与eventfd有什么区别呢?

两者都是内核变量,eventfd的优势在于,它可以作为文件fd来读写,同时还可以使用poll/select实现异步等待,也就是说eventfd在等待时,你还可以干别的事,如果有可读时,你再去读;而信号量则不行,只能是等待或者不等待。

 

接口说明

 

头文件

 #include <sys/eventfd.h>

 

创建eventfd类型的句柄

int eventfd(unsigned int initval, int flags);

 

参数说明

initval

计数的初值

flags

EFD_CLOEXEC:

在调用exec创建进程时会自动关闭fd。

 

EFD_NONBLOCK:

创建非阻塞模式的fd,也就是在计数为0时,不会等待,直接返回-1;不指定时,默认为阻塞模式。

 

EFD_SEMAPHORE:

创建类似信号量的模式,如果计数大于0时,每次读到的是1,同时计数自动减1,到0时阻塞。

不指定时,每次读全部累计值,计数被重置为0。

 

代码演示

默认参数

先看一个默认参数,默认是阻塞模式,每次都会取累计值,并重置eventfd中的累计值为零;如果累计值为0,则会阻塞。

#include <sys/eventfd.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>             /* Definition of uint64_t */

int main(int argc, char *argv[])
{
        int efd;
        uint64_t u = 0;
        ssize_t s;

    efd = eventfd(0, 0);
    if (efd == -1)
                return -1;

        u = 0x01;
        printf("write eventfd %llu \n", u);
    s = write(efd, &u, sizeof(uint64_t));

        u = 0x02;
        printf("write eventfd %llu \n", u);
        s = write(efd, &u, sizeof(uint64_t));

        u = 0x03;
        printf("write eventfd %llu \n", u);
        s = write(efd, &u, sizeof(uint64_t));

        s = read(efd, &u, sizeof(uint64_t));
    if (s != sizeof(uint64_t))
        {
                printf("read failure.\n");
        }

        printf("read %llu from efd\n", u);

        close(efd);

        return 0;
}

信号量模式

再来看一下使用信号量模式的效果,虽然写入了几次,但是每次read只读出1,累计值也是每次都会减1;

#include <sys/eventfd.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>             /* Definition of uint64_t */

int main(int argc, char *argv[])
{
        int efd;
        uint64_t u = 0;
        ssize_t s;

    efd = eventfd(0, EFD_SEMAPHORE);
    if (efd == -1)
                return -1;

        u = 0x01;
        printf("write eventfd %llu \n", u);
    s = write(efd, &u, sizeof(uint64_t));

        u = 0x02;
        printf("write eventfd %llu \n", u);
        s = write(efd, &u, sizeof(uint64_t));


        s = read(efd, &u, sizeof(uint64_t));
        if (s != sizeof(uint64_t))
        {
                printf("read failure.\n");
        }

        printf("read %llu from efd\n", u);

        s = read(efd, &u, sizeof(uint64_t));
        if (s != sizeof(uint64_t))
        {
                printf("read failure.\n");
        }

        printf("read %llu from efd\n", u);

        s = read(efd, &u, sizeof(uint64_t));
        if (s != sizeof(uint64_t))
        {
                printf("read failure.\n");
        }

        printf("read %llu from efd\n", u);

        close(efd);

        return 0;
}

 

 


结尾

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。另外有什么想要了解的内容,也可以给我发邮件,互相谈讨,定知无不言。

注:未经同意,不得转载!

 

 

 

到了这里,关于linux eventfd事件通知 比信号量更好用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • linux信号量

    通过学习linux的信号量,对linux的信号量进行了编程。

    2024年02月10日
    浏览(35)
  • linux(信号量)

    1.回顾信号量的概念 2.认识信号量对应的操作函数 3.认识一个环形队列 4.结合sem+环形队列写生产者消费者模型 --------------------------------------------------------------------------------------------------------------------------------- 1.回顾信号量的概念  每个人想进放映厅看电影,第一件事就是买票

    2024年02月11日
    浏览(35)
  • 【Linux】浅谈信号量

    tips:system V 是一套标准,共享内存,信号量,消息队列属于system V。 进程A和进程B进行通信时,假如进程A向物理内存的共享区写入\\\"Hello World\\\",但是当进程A写入了\\\"Hello\\\"时,进程B就向内存读取了,所以只读取到了\\\"Hello\\\",这就导致进程A想向进程B发送的信息,进程B读取不完整,

    2024年02月05日
    浏览(38)
  • 【Linux】进程间通信 -- 信号量

    信号量是什么? 本质是一个计数器,通常用来表示公共资源中,资源数量多少的问题 公共资源:能被多个进程同时可以访问的资源 访问没有保护的公共资源:数据不一致问题(比如我想写abc123,但是我123还没有写入,就读取了abc,可能数据分开会导致数据无意义) 为什么要

    2024年02月16日
    浏览(39)
  • linux进程间通信(信号量)

    信号量是一个特殊的变量,程序对其访问都是原子操作,且只允许对它进行等待(即 P(信号变量))和发 送(即 V(信号变量))信息操作。最简单的信号量是只能取 0 和 1 的变量,这也是信号量最常见的一种形式, 叫做二进制信号量。而可以取多个正整数的信号量被称为通用信号

    2024年02月07日
    浏览(29)
  • 【Linux篇】第十七篇——信号量

    前言 POSIX信号量 信号量的概念 信号量的工作原理 信号量函数 二元信号量模拟实现互斥功能 基于环形队列的生产消费模型 空间资源和数据资源 生产者和消费者申请和释放资源 必须遵守的两个规则 代码实现 信号量保护环形队列的原理 将可能被多个执行流同时访问的资源叫

    2024年02月06日
    浏览(37)
  • linux(system V标准)信号量

    目录:             1.什么是信号量             2.信号量的本质 1.什么是信号量   2.信号量的本质  什么是临界资源呢?? 凡是倍多个执行流同时访问的资源就是临界资源!!! 我们看一个问题,我们fork()之后创建一个子进程,那么我们的全局变量,是不是我们父

    2024年02月07日
    浏览(33)
  • Linux进程间通信【消息队列、信号量】

    ✨个人主页: 北 海 🎉所属专栏: Linux学习之旅 🎃操作环境: CentOS 7.6 阿里云远程服务器 在 System V 通信标准中,还有一种通信方式: 消息队列 ,以及一种实现互斥的工具: 信号量 ;随着时代的发展,这些陈旧的标准都已经较少使用了,但作为 IPC 中的经典知识,我们可

    2024年02月08日
    浏览(30)
  • 【Linux】多线程 之 POSIX信号量

    信号量又称为 信号灯 本质就是一个计数器,用于描述临界资源数目的 sem: 0 - 1 - 0 若临界资源只有1个,则sem设为1,当要使用临界资源时,sem由1变为0,其他人在想申请,则申请不到挂起排队,等待释放临界资源时 sem由0变为1 ,才可以再申请临界资源 这种信号量称为 二元信号

    2024年02月16日
    浏览(39)
  • 『Linux』第九讲:Linux多线程详解(五)_ 信号量

    「前言」文章是关于Linux多线程方面的知识,上一篇是 Linux多线程详解(四),今天这篇是 Linux多线程详解(五),内容大致是信号量,讲解下面开始! 「归属专栏」Linux系统编程 「主页链接」个人主页 「笔者」枫叶先生(fy) 「枫叶先生有点文青病」「每篇一句」 求其上,

    2024年02月07日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包