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

  74ac905cfa3740079f2f66a445a3d7c2.gif#pic_center

 

  • 专栏内容: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
如有错误或者疏漏欢迎指出,互相学习。另外有什么想要了解的内容,也可以给我发邮件,互相谈讨,定知无不言。

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

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/3802.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

探讨绿色照明与智能照明节能控制系统应用

张心志 安科瑞电气股份有限公司 上海嘉定 201801 【摘 要】随着社会经济的不断发展&#xff0c;人们对生活质量、环境品质越发重视。积极推广绿色智能照明&#xff0c;提高城市照明质量&#xff0c;对于改善人们居住环境意义重大。文章简要介绍了绿色照 明的基本要求、室内智…

Excel 经常复制粘贴失效,复制表格粘贴不了无反应,怎么解决?

环境&#xff1a; Win10 专业版 Excel2021 L盾加密客户端 wps2021 问题描述&#xff1a; 之前正常的&#xff0c;excel2016和2021 经常复制表格粘贴不了无反应每隔10几分钟随机出现&#xff0c;在表格外面复制粘贴没有问题&#xff0c;把外面东西&#xff0c;粘贴进表格里…

UE5 Stride Warping Orientation Warping功能学习

在UE5的 Lyra Demo中&#xff0c;运用到了各类动画Warping&#xff08;动画扭曲&#xff09;技术&#xff0c;通过各类Warping节点在动画蓝图中的合理组织&#xff0c;可以有效的解决运动滑步问题&#xff0c;并为动画增添更多细节。 本文主要基于Animation Warping插件讲一下…

SQL中的——左连接(Left join)、右连接(Right join)、内连接(Inner join)

前言 最近有一个开发需求&#xff0c;需要实现一个复杂年度报表&#xff0c;前后端都是博主开发&#xff0c;这里的业务逻辑比较复杂&#xff0c;也很锻炼sql能力&#xff0c;这里博主也将表的内外连接做了一个整理分享给大家 一、概念 首先还是介绍一下这三个的定义 1.Lef…

PHP 基础知识

目录 PHP基础 2 PHP代码标记 2 PHP注释 2 PHP语句分隔符 2 PHP变量 3 常量 3 数据类型 4 流程控制 6 文件 7 函数 9 闭包 11 常用系统函数 12 错误处理 13 错误显示设置 15 字符串类型 17 字符串相关函数 19 数组 21 遍历数组 22 数组的相关函数 25 PHP基础 PHP是一种运行在服务…

在虚幻引擎中创建大气的HIMIL电影作品

今天瑞云渲染小编给大家带来了关于电影制片人Tiziano Fioriti展示了《H I M I L》项目背后的工作流程&#xff0c;解释了人工智能是如何用于细节的&#xff0c;并谈到了设置火光的问题。 介绍 大家好&#xff0c;我叫Tiziano Fioriti&#xff0c;是来自意大利的自由电影制作人…

我们来谈谈websocket

"你一无所有地闯荡。" 一、初始WebSocket (1) 什么是websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议。 WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。在WebSocket API中&#xff0c;浏览器和…

(动态规划) 673. 最长递增子序列的个数 ——【Leetcode每日一题】

❓ 673. 最长递增子序列的个数 难度&#xff1a;中等 给定一个未排序的整数数组 nums &#xff0c; 返回最长递增子序列的个数 。 注意 这个数列必须是 严格 递增的。 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列&#xff0c;分别是 [1, 3, 4, 7] 和[1,…

【http服务】使用命令来查看和停止端口

需求: 在Windows 10上&#xff0c;使用命令来查看和停止端口8000上的进程。 方法&#xff1a; 要查看所有端口以及它们所属的进程&#xff0c;您可以使用以下命令&#xff1a; Get-NetTCPConnection | Select-Object LocalPort, OwningProcess这将显示所有TCP连接的本地端口…

游戏陪玩语音聊天系统3.0商业升级独立版本源码

首发价值29800元的最新商业版游戏陪玩语音聊天系统3.0商业升级独立版本源码 1、增加人气店员轮播 2、优化ui界面丨优化游戏图标展示丨优化分类展示 3、增加动态礼物打赏功能 4、增加礼物墙功能 增加店员满足业绩&#xff0c;才能升级功能 5、增加店员等级不同&#xff0c;可接…

软件测试的概念与过程----学习软件测试前的思考

软件测试的概念与过程----学习软件测试前的思考 1、软件测试工作是做什么的&#xff1f;2、那我做软件测试拿到一个软件产品我应该从哪里测试&#xff0c;怎末开始工作&#xff1f;3、测试早做好还是晚一些做好&#xff1f;4、软件测试能将软件测试的一点问题都没有嘛&#xff…

Day43

思维导图 深拷贝和浅拷贝 1> 如果类中有指针成员时&#xff0c;如果没有显性的定义拷贝构造和拷贝赋值函数&#xff0c;系统默认提供的都只能实现浅拷贝&#xff0c;需要显性定义出深拷贝函数&#xff0c;为了完成指针成员的独立赋值&#xff0c;如果类中没有指针成员&#…