eventfd和timerfd学习笔记

一、eventfd

1.1简介:

eventfd是进程间通信(IPC)的一种手段,主要用来做事件通知。IPC通常方式:

1)unix socket

2)pipe

3)共享内存

前两种都是同步调用,但是传递大量数据时存在效率问题,而使用共享内存效率高,但是缺乏同步通知机制,消费者轮询共享内存修改开销太大。这里可以使用eventfd用来做同步。

1.2 使用

eventfd每次只能发送8个字节的内容(flag),一般用于每个bit表示一个消息类型。

  • API

1)创建文件句柄:

#include <sys/eventfd.h>
int eventfd(unsigned int initval, int flags);

2)消息发送

// 写 eventfd,内部 buffer 必须是 8 字节大小;
n = write(efd, &u, sizeof(uint64_t));

3)消息接收

// 读 eventfd
n = read(efd, &u, sizeof(uint64_t));

写数据时会累加flag,读数据后flag清零。所以这里发送消息时可以同时发送多个消息。

实例:

// 写 3 次,发3次消息
write(efd, &u /* u = 0x01 */ , 8)
write(efd, &u /* u = 0x02 */ , 8)
write(efd, &u /* u = 0x04 */ , 8)

读数据时,会读到累加的数据

read(ebd, &x, 8) /*读到x = 0x7*/
  • 使用场景2

eventfd可以用于进程间信号量的作用,生产者每次写入1,消费者每次取出1然后执行。不过需要打开选项:

EFD_SEMAPHORE (since Linux 2.6.30)Provide  semaphore-like semantics for reads from the new file descriptor.  Seebelow.

查看fd信息

zfj@ubuntu22:/proc/5686/fd$ ls -l
total 0
lrwx------ 1 zfj zfj 64  5月 19 21:37 0 -> /dev/pts/1
lrwx------ 1 zfj zfj 64  5月 19 21:37 1 -> /dev/pts/1
lrwx------ 1 zfj zfj 64  5月 19 21:37 2 -> /dev/pts/1
lrwx------ 1 zfj zfj 64  5月 19 21:37 3 -> 'anon_inode:[eventfd]'

eventfd是匿名fd,指没有对应具体文件。

  • 实战

eventfd支持poll机制,可使用poll和select接口监听。

#include <malloc.h>
#include <pthread.h>
#include <zconf.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <wait.h>
#include <sys/eventfd.h>#define handle_error(msg)   \do { perror(msg); exit(EXIT_FAILURE);  } while(0)
int main(int argc, char** argv)
{int  efd;ssize_t rc;efd = eventfd(0, 0);if(-1 == efd){handle_error("eventfd");}printf("efd=%d\n", efd);int ret = fork();uint64_t buf;if (ret == 0){/*消费者*/printf("wait for read:\n");rc = read(efd, &buf, sizeof(uint64_t));printf("read finished: %zd\n", rc);printf("Parent read %llu from efd\n",(unsigned long long)buf);return 0;}else{/*生产者*/buf = 0x5;rc = write(efd, &buf, sizeof(uint64_t));printf("after write\n");	 }
}

问题:

event没有做标识?所有进程都只能用同一组?系统中只能存在一组eventfd?

static const struct file_operations eventfd_fops = {
#ifdef CONFIG_PROC_FS
.show_fdinfo = eventfd_show_fdinfo,
#endif
.release = eventfd_release,
.poll = eventfd_poll,
.read_iter = eventfd_read,
.write = eventfd_write,
.llseek = noop_llseek,
};

eventfd没有open函数,只有一个eventfd的系统调用。

所以仅限于fork出来的进程,只能用于主子进程间。

1.3 内核实现

《fs/eventfd.c》

1.4 参考资料

Linux fd 系列 — eventfd 是什么? - 知乎 (zhihu.com)

二、timerfd

2.1 简介

timerfd可用于用户态的定时器,定时操作。

2.2 使用

  • API
// 创建一个 timerfd 句柄
/*clockid
* CLOCK_MONOTONIC:开机到现在的时间,不可设置的时间
* CLOCK_REALTIME:实时时间,到时间点执行,可重设时间点
* 
*/
int timerfd_create(int clockid, int flags);
// 启动或关闭 timerfd 对应的定时器
int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value);
// 获取指定 timerfd 距离下一次超时还剩的时间
int timerfd_gettime(int fd, struct itimerspec *curr_value);

数据结构

struct timespec64 {time64_t	tv_sec;			/* seconds */long		tv_nsec;		/* nanoseconds */
};struct itimerspec64 {/*开始执行后,每次间隔多久执行一次*/struct timespec64 it_interval;/*settime后多久开始执行*/struct timespec64 it_value;
};
  • 实战

timerfd 绑定的是匿名 inode,eventfd也是匿名inode

#include <stdio.h>
#include <sys/timerfd.h>
#include <poll.h>
#include <unistd.h>
#include <assert.h>int main() {struct itimerspec timebuf;int timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);/*开始运行后每1s执行一次*/timebuf.it_interval.tv_sec = 1;timebuf.it_interval.tv_nsec = 0;	  // period timeout value = 1s/*第一次执行设置后5s开始执行*/timebuf.it_value.tv_sec = 5;timebuf.it_value.tv_nsec = 0;  // initial timeout value = 5stimerfd_settime(timerfd, 0, &timebuf, NULL);struct pollfd fds[1];int len = sizeof(fds) / sizeof(fds[0]);fds[0].fd = timerfd;fds[0].events = POLLIN | POLLERR | POLLHUP;while (1){int n = poll(fds, len, -1);for (int i = 0; i < len && n-- > 0; ++i) {if (fds[i].revents & POLLIN){unsigned long long val;int ret = read(timerfd, &val, sizeof(val));if (ret != sizeof(val)) // ret should be 8{printf("ret bytes instead of 8 frome timerfd\n");break;}printf("timerfd = %d timeout\n", timerfd);}}}close(timerfd);return 0;
}

2.3 内核实现

static const struct file_operations timerfd_fops = { .release    = timerfd_release,.poll       = timerfd_poll,.read       = timerfd_read,.show_fdinfo    = timerfd_show,// ...
};

定时器的poll操作用于定时,读操作获取下一次超时剩余时间。

《fs/timerfd.c》

2.4 参考资料

Linux fd 系列 — 定时器 timerfd 是什么? - 知乎 (zhihu.com)

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

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

相关文章

FPGA搭积木之按键消抖(改进版)

目录 1.前言 2.回顾之前的设计 3.基于读者思路的设计 4.ModelSim仿真 1.前言 昨天分享的关于FPGA对机械按键消抖的设计&#xff0c;有读者指出了其中的不足&#xff0c;并给出了他的思路。今天就读者的设计思路&#xff0c;来再做一个按键消抖模块。这个程序大概是大学的时…

亚马逊、eBay、沃尔玛、OZON、速卖通等平台自养号攻略,助力测评补单

当前&#xff0c;跨境电商面临着巨大的挑战&#xff0c;其运营环境日益变得错综复杂。然而&#xff0c;这种复杂性可以归结为两个核心元素&#xff1a;买与刷。商家们通过进行买卖交易或补单操作&#xff0c;旨在增加销售、提升产品排名&#xff0c;并进而增强产品的权重。 销…

docker-如何将容器外的脚本放入容器内,将容器内的脚本放入容器外

文章目录 前言docker-如何将容器外的脚本放入容器内&#xff0c;将容器内的脚本放入容器外、1. docker 如何将容器外的脚本放入容器内1.1. 验证 2. 将容器内的脚本放入容器外 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&…

VMware Workstation 虚拟机安装 ubuntu 24.04 server 详细教程 服务器安装图形化界面

1 阿里云下载 ubuntu-releases安装包下载_开源镜像站-阿里云 2 打开vmware,新建虚拟机 3 选择下载的镜像,开始安装 3 光驱这里修改下 4 重新启动&#xff0c;安装图形化界面 #更新软件包列表 sudo apt-get update #安装Ubuntu图形桌面 sudo apt install ubuntu-desktop 5 安…

hudi相关疑问

标题 1、flink流式写入hudi表时&#xff0c;Changelog模式和Append模式区别Changelog 模式Append 模式配置示例配置 Append 模式配置 Changelog 模式 总结 2、flink流式写入hudi表时&#xff0c;设置了Changelog模式&#xff0c;还需要设置write.operation参数吗Changelog 模式…

Python集合与字典的概念与使用-课堂练习[python123题库]

集合与字典的概念与使用-课堂练习 一、单项选择题 1、 哪个选项是下面代码的输出结果&#xff1f;‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬…

【调试笔记-20240524-Linux-扩展 OpenWrt-23.05 发行版 EXT4 镜像文件大小】

调试笔记-系列文章目录 调试笔记-20240524-Linux-扩展 OpenWrt-23.05 发行版 EXT4 镜像文件大小 文章目录 调试笔记-系列文章目录调试笔记-20240524-Linux-扩展 OpenWrt-23.05 发行版 EXT4 镜像文件大小 前言一、调试环境操作系统&#xff1a;Ubuntu 22.04.4 LTS工作环境调试目…

在https的系统中挂载其他http系统的画面的解决方案

目录 1.问题及说明 2.解决方案及示例 3.总结 1.问题及说明 A系统使用了https&#xff0c;在A系统中挂载B系统的http的画面&#xff0c;会报错如下&#xff1a; Mixed Content: The page at https://beef.zz.com/front/#/biz/cultivationList/cultivationDetails/5dbf836751…

MySQL之架构设计与历史(五)

MySQL之架构设计与历史 MyISAM存储引擎 在MySQL5.1及之前的版本&#xff0c;MyISAM是默认的存储引擎。MyISAM是默认的存储引擎。MyISAM提供了大量的特性&#xff0c;包括全文索引、压缩、空间函数(GIS)等&#xff0c;但MyISAM不支持事务和行级锁&#xff0c;而且有一个毫无疑…

【SD-WAN】香港企业进入粤港澳大湾区所面临的机遇和挑战

粤港澳大湾区发展及规划是中国其中一个主点发展战略&#xff0c;具备完整的多元化产业结构&#xff0c;城市之间建立强大的经济互补性&#xff0c;是国际性湾区和世界级城市群。因此&#xff0c;大湾区近年吸引了不少香港的创新及科技企业前往发展投资及设立据点扩展业务。本文…

增强版 Kimi:AI 驱动的智能创作平台,实现一站式内容生成(图片、PPT、PDF)!

前言 基于扣子 Coze 零代码平台&#xff0c;我们从零到一轻松实现了专属 Bot 机器人的搭建。 AI 大模型&#xff08;LLM&#xff09;、智能体&#xff08;Agent&#xff09;、知识库、向量数据库、知识图谱&#xff0c;RAG&#xff0c;AGI 的不同形态愈发显现&#xff0c;如何…

SpringBoot中注解@RestController | @ResponseBody | @Controller

ResponseBody 可以修饰类和方法 Controller 和 RestController 只能修饰类 RestController 告诉Spring&#xff0c;帮我们管理这个代码&#xff0c;我们后续访问时&#xff0c;才能访问到 RequestMapping 路由映射&#xff0c;可以修饰方法&#xff0c;也可以修饰类 访问地址…

【代码随想录37期】Day16 二叉树的最大深度、二叉树的最小深度、完全二叉树的节点个数

二叉树的最大深度 v1.0:迭代法 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right…

【Linux网络编程】IO多种转接之Reactor

Reactor 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 基于上一篇epoll的学习&#xff0c;现在我们也知道epoll的工作模式有两种&#xff0c…

【UE5.1 多线程 异步】“Async Blueprints Extension”插件使用记录

目录 一、异步生成Actor示例 二、异步计算示例 参考视频 首先需要在商城中下载“Async Blueprints Extension”插件 一、异步生成Actor示例 2. 创建一个线程类&#xff0c;这里要指定父类为“LongAsyncTask”、“InfiniteAsyncTask”、“ShortAsyncTask”中的一个 在线程类…

el-table 实现嵌套表格的思路及完整功能代码

要实现的需求是这样的&#xff1a; 本来我是用 el-table 的 :span-method 方法实现的&#xff0c;但发现合并起来有问题&#xff0c;跟我的需求差距有些大&#xff0c;于是我想到了嵌套表格。但是嵌套完之后的样子也是很奇怪&#xff1a; 不要气馁&#xff0c;思路还是对的&a…

基于文心智能体平台打造专属情感类陪伴智能体【情绪价值提供者】

文章目录 一、文心智能体平台介绍二、文心智能体平台注册三、智能体介绍四、智能体创建过程4.1 基础配置4.2 高级配置4.3 预览调优4.4 公开发布 五、智能体使用心得六、智能体分享方式七、参考链接 一、文心智能体平台介绍 文心智能体平台是百度推出的基于文心大模型的智能体&…

计算机毕业设计 | springboot药品库存追踪与管理系统 药店管理(附源码)

1&#xff0c;绪论 1.1 背景调研 如今药品调价频繁&#xff0c;且品种繁多&#xff0c;增加了药品销售定价的难度。药品来货验收登记中的审查有效期环节容易出错&#xff0c;错收过期或有效期不足的药品。 手工模式下的药品库存难以及时掌握&#xff0c;虽然采取了每日进行缺…

Flask CORS: 解决跨域资源共享问题的利器

文章目录 安装和启用 CORS配置 CORS拓展 在本文中&#xff0c;我们介绍了如何使用 Flask-CORS 扩展来解决跨域问题。Flask-CORS 是一个方便的工具&#xff0c;可以帮助我们轻松地实现跨域资源共享支持。 安装和启用 CORS 要开始使用 Flask-CORS&#xff0c;我们需要先安装它。…

机器学习模型可视化分析和诊断神器Yellowbrick

大家好&#xff0c;机器学习(ML)作为人工智能的核心&#xff0c;近来得到巨大应用&#xff0c;ML是使计算机能够在无需显式编程的情况下进行学习和预测或决策。ML算法通过学习历史数据模式&#xff0c;来对新的未见数据做出明智的预测或决策。然而&#xff0c;构建和训练ML模型…