Linux指南:详解eventfd(2)功能的中文翻译与介绍
eventfd - 为event notification创建文件描述符
#include <sys/eventfd.h>
int eventfd(unsigned int initval, int flags);
eventfd() 创建了一个“eventfd 对象”,它可以被用户空间应用程序用作事件等待/通知机制,内核可以将事件通知用户空间应用程序。 该对象包含一个由内核维护的无符号 64 位整数 (uint64_t) 计数器。 此计数器使用参数 initval
中指定的值进行初始化。
eventfd() 将返回一个文件描述符,指向“eventfd 对象”。
参数 flag 可以是以下值按位或运算:
-
EFD_CLOEXEC
对应于open的 O_CLOEXEC 参数,即在执行execve是关闭此fd -
EFD_NONBLOCK
对应于open的 O_NONBLOCK 参数,即将其设置非阻塞的fd,如果fd处于不可读写的状态,读写非阻塞的fd将不会阻塞线程,而是返回 EAGAIN -
EFD_SEMAPHORE
赋予eventfd类似于信号量的语义。 见下文。
在 Linux 2.6.26 之前的版本中,flags
参数未使用,必须指定为零。
可以对 eventfd() 返回的文件描述符执行以下操作:
read(2)
成功读取会返回一个 8 字节整数。 如果提供的缓冲区的大小小于 8 字节,则 read(2) 失败并显示错误 EINVAL。
read(2) 返回的值是主机字节顺序,即主机上整数的本机字节顺序。换句话说,返回的值可以直接转化为整数。
read(2) 的语义取决于 eventfd 计数器当前是否具有非零值以及在创建 eventfd 文件描述符时是否指定了 EFD_SEMAPHORE 标志:
- 如果未指定 EFD_SEMAPHORE 并且 eventfd 计数器具有非零值,则 read(2) 返回 eventfd 计数器的值,同时将计数器置零。
- 如果指定了 EFD_SEMAPHORE 并且 eventfd 计数器具有非零值,则 read(2) 返回1,同时将计数器的值减 1。
- 如果在调用 read(2) 时 eventfd 计数器为零则:
- 未配置EFD_NONBLOCK flags,则调用阻塞,直到计数器变为非零(此时,read(2) 如上所述返回结果)
- 若配置了EFD_NONBLOCK flags,则调用失败并返回错误 EAGAIN
write(2)
write(2) 调用将其缓冲区中提供的 8 字节整数值添加到计数器(计数器的值加上write提供的值)。计数器的最大值为2^64-1(即0xffffffffffffffffe),如果相加的结果超过最大值,那么将阻塞write(),直到执行read(),当然,如果设置了EFD_NONBLOCK flags,则调用失败并返回错误 EAGAIN
poll(2), select(2),epoll(7)
- 如果计数器的值大于 0,则文件描述符是可读的(epoll(2) POLLIN 标志)。
- 如果可以在不阻塞的情况下写入至少为“1”的值,则文件描述符是可写的(epoll(2) POLLOUT 标志),即当前计数器不是最大值。
- 如果检测到计数器值溢出,则 select(2) 将文件描述符指示为可读和可写,并且 poll(2) 返回一个 POLLERR 事件。 如上所述,write(2) 永远不会溢出计数器。 但是,如果 KAIO 子系统执行了 2^64 个 eventfd“信号发布”,则可能会发生溢出(理论上可能,但实际上不太可能)。 如果发生溢出,则 read(2) 将返回该最大 uint64_t 值(即 0xffffffffffffffff)。
eventfd 文件描述符还支持其他文件描述符多路复用 API:pselect(2) 和 ppoll(2)。
close(2)
当不再需要文件描述符时,应将其关闭。 当与同一个 eventfd 对象关联的所有文件描述符都已关闭时,内核会释放对象的资源。
由 eventfd() 创建的文件描述符的副本由 fork(2) 生成的子进程继承。 重复的文件描述符与相同的 eventfd 对象相关联。 除非设置了 close-on-exec 标志,否则 eventfd() 创建的文件描述符将在 execve(2) 中保留。
成功时, eventfd() 返回一个新的 eventfd 文件描述符。 出错时,返回 -1 并设置 errno 以指示错误。
EINVAL
在FLAGS
中指定了不支持的值。EMFILE
达到了每个进程可打开的文件描述符数目的上限EMFILE
达到了系统可打开的文件描述符数目的上限ENODEV
无法挂载(内部)匿名 inode 设备。ENOMEM
内存不足,无法创建新的 eventfd 文件描述符。
eventfd() is available on Linux since kernel 2.6.22. Working support is provided in glibc since version 2.8. The eventfd2() system call (see NOTES) is available on Linux since kernel 2.6.27. Since version 2.9, the glibc eventfd() wrapper will employ the eventfd2() system call, if it is supported by the kernel.
Interface | Attribute | Value |
---|---|---|
eventfd() | Thread safety | MT-Safe |
eventfd() and eventfd2() are Linux-specific.
在管道仅用于发送事件信号的所有情况下,应用程序都可以使用 eventfd 文件描述符而不是管道(请参阅 pipe(2))。 eventfd 文件描述符的内核开销远低于管道,并且只需要一个文件描述符(而管道需要两个)。
当在内核中使用时,eventfd 文件描述符可以提供从内核到用户空间的桥梁,例如,允许诸如 KAIO(内核 AIO)之类的功能向文件描述符发出信号,表明某些操作已完成。
eventfd 文件描述符的一个关键点是它可以像任何其他文件描述符一样使用 select(2)、poll(2) 或 epoll(7) 进行监视。这意味着应用程序可以同时监视“传统”文件的准备情况和支持 eventfd 接口的其他内核机制的准备情况。 (没有 eventfd() 接口,这些机制无法通过 select(2)、poll(2) 或 epoll(7) 进行多路复用。)
在进程的 /proc/[pid]/fdinfo 目录中,可以通过相应文件描述符的条目查看 eventfd 计数器的当前值。有关更多详细信息,请参阅 proc(5)。
C library/kernel differences
有两个底层的 Linux 系统调用:eventfd() 和最近的 eventfd2()。 前一个系统调用没有实现 flags 参数。 后一个系统调用实现了上述标志值。 glibc 包装器函数将在可用的地方使用 eventfd2()。
Additional glibc features
GNU C 库定义了一个额外的类型和两个函数,它们试图抽象一个 eventfd 文件描述符的一些读写细节:
typedef uint64_t eventfd_t;
int eventfd_read(int fd, eventfd_t *value);
int eventfd_write(int fd, eventfd_t value);
这些函数对 eventfd 文件描述符执行读写操作,如果传输的字节数正确则返回 0,否则返回 -1。
下面的程序创建一个 eventfd 文件描述符,然后 fork 创建一个子进程。 当父进程短暂休眠时,子进程将程序命令行参数中提供的每个整数写入 eventfd 文件描述符。 当父进程完成睡眠后,它从 eventfd 文件描述符中读取。
以下 shell 会话显示了程序的示例运行:
$ ./a.out 1 2 4 7 14
Child writing 1 to efd
Child writing 2 to efd
Child writing 4 to efd
Child writing 7 to efd
Child writing 14 to efd
Child completed write loop
Parent about to read
Parent read 28 (0x1c) from efd
源代码:
#include <sys/eventfd.h>
#include <unistd.h>
#include <inttypes.h> /* Definition of PRIu64 & PRIx64 */
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h> /* Definition of uint64_t */
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
int
main(int argc, char *argv[])
{
int efd;
uint64_t u;
ssize_t s;
if (argc < 2) {
fprintf(stderr, "Usage: %s <num>...\n", argv[0]);
exit(EXIT_FAILURE);
}
efd = eventfd(0, 0);
if (efd == -1)
handle_error("eventfd");
switch (fork()) {
case 0:
for (int j = 1; j < argc; j++) {
printf("Child writing %s to efd\n", argv[j]);
u = strtoull(argv[j], NULL, 0);
/* strtoull() allows various bases */
s = write(efd, &u, sizeof(uint64_t));
if (s != sizeof(uint64_t))
handle_error("write");
}
printf("Child completed write loop\n");
exit(EXIT_SUCCESS);
default:
sleep(2);
printf("Parent about to read\n");
s = read(efd, &u, sizeof(uint64_t));
if (s != sizeof(uint64_t))
handle_error("read");
printf("Parent read %"PRIu64" (%#"PRIx64") from efd\n", u, u);
exit(EXIT_SUCCESS);
case -1:
handle_error("fork");
}
}
推荐阅读
-
【2022新手指南】Java编程进阶之路 - 六、技术架构篇 ### MySQL索引底层解析与优化实战 - 你会讲解MySQL索引的数据结构吗?性能调优技巧知多少? - Redis深度揭秘:你知道多少?从基础到哨兵、主从复制全梳理 - Redis持久化及哨兵模式详解,还有集群搭建和Leader选举黑箱打开 - Zookeeper是个啥?特性和应用场景大公开 - ZooKeeper集群搭建攻略及 Leader选举、读写一致性、共享锁实现细节 - 探究ZooKeeper中的Leader选举机制及其在分布式环境中的作用 - Zab协议深入剖析:原理、功能与在Zookeeper中的核心地位 - RabbitMQ全方位解读:工作模式、消费限流、可靠投递与配置策略 - 设计者视角:RabbitMQ过期时间、死信队列与延时队列实践指南 - RocketMQ特性和应用场景揭示:理解其精髓与差异化优势 - Kafka详细介绍:特性及广泛应用于实时数据处理的场景解析 - ElasticSearch实力揭秘:特性概述与作为搜索引擎的广泛应用 - MongoDB认知升级:非关系型数据库的优势阐述,安装与使用实战教学 - BIO/NIO/AIO网络模型对比:掌握它们的区别与在网络编程中的实际应用 - Netty带你飞:理解其超快速度背后的秘密,包括线程模型分析 - 网络通信黑科技:Netty编解码原理与常用编解码器的应用,Protostuff实战演示 - 解密Netty粘包与拆包现象,怎样有效应对这一常见问题 - 自定义Netty心跳检测机制,轻松调整检测间隔时间的艺术 - Dubbo轻骑兵介绍:核心特性概览,服务降级实战与其实现益处 - Dubbo三大神器解读:本地存根与本地伪装的实战运用与优势呈现 ----------------------- 七、结语与回顾
-
` 自动填充为 `cp test.txt`
- 文件和目录名补全:输入文件名首字母后按 Tab,如 `vi ed
` 显示可用的编辑器列表 - 查看命令帮助: - 使用 `man` 命令配合具体命令名获取详尽帮助,如 `man ls` 或者 `man grep --help`"> 在 Linux 中操作指令指南 - 基本构造与种类 - 指令组成: 1. **主指令 + 选项 + 参数**: 如 `ls -l /home`,`main-action option object` - 内置指令:系统预装的 shell 功能,如 `cd`, `pwd` - 外部指令:独立可执行文件,直接用文件名当作命令,如 `rm`, `mv` - **选项与参数**: - 选项:定制命令行为, `-l` 或 `--long-help` - 短选项:简写形式,例如 `-v` 和 `-V` 可能合并使用 - 长选项:详细描述的选项,如 `--version` 或 `--human-readable` - 参数:命令作用的目标,如 `ls` 对 `/home` 目录的操作 - **指令应用**: - 不同指令需要不同的参数 - 选项可带或不带参数,比如 `grep -i "keyword"` (忽略大小写搜索) - 参数间通常用空格分隔,如 `cp file1 file2 file3` - **中断与完成提示**: - 终止当前指令:按下 Ctrl+C - **自动完成**: - 输入部分命令关键词后,按 Tab 键补全命令,如 `cp ta
` 自动填充为 `cp test.txt` - 文件和目录名补全:输入文件名首字母后按 Tab,如 `vi ed ` 显示可用的编辑器列表 - 查看命令帮助: - 使用 `man` 命令配合具体命令名获取详尽帮助,如 `man ls` 或者 `man grep --help` -
理解深度学习基础:从神经网络构造到实践 - 1.评分函数介绍 2.SVM损失函数解析 3.正规化惩罚项说明 4.Softmax与交叉熵损失函数详解 5.前向传播中的最优化挑战 6.批量大小(batch_size)实操指南...
-
Linux指南:深入理解madvise(2)函数的翻译与详解
-
Linux指南:详解eventfd(2)功能的中文翻译与介绍
-
包婷婷 (201550484)作业一 统计软件简介与数据操作-SPSS(Statistical Product and Service Solutions),"统计产品与服务解决方案"软件。最初软件全称为"(SolutionsStatistical Package for the Social Sciences),但是随着SPSS产品服务领域的扩大和服务深度的增加,SPSS公司已于2000年正式将英文全称更改为"统计产品与服务解决方案",标志着SPSS的战略方向正在做出重大调整。为IBM公司推出的一系列用于统计学分析运算、数据挖掘、预测分析和决策支持任务的软件产品及相关服务的总称SPSS,有Windows和Mac OS X等版本。 1984年SPSS总部首先推出了世界上第一个统计分析软件微机版本SPSS/PC+,开创了SPSS微机系列产品的开发方向,极大地扩充了它的应用范围,并使其能很快地应用于自然科学、技术科学、社会科学的各个领域。世界上许多有影响的报刊杂志纷纷就SPSS的自动统计绘图、数据的深入分析、使用方便、功能齐全等方面给予了高度的评价。 R统计软件介绍 R是一套完整的数据处理、计算和制图软件系统。其功能包括:数据存储和处理系统;数组运算工具(其向量、矩阵运算方面功能尤其强大);完整连贯的统计分析工具;优秀的统计制图功能;简便而强大的编程语言:可操纵数据的输入和输出,可实现分支、循环,用户可自定义功能。 与其说R是一种统计软件,还不如说R是一种数学计算的环境,因为R并不是仅仅提供若干统计程序、使用者只需指定数据库和若干参数便可进行一个统计分析。R的思想是:它可以提供一些集成的统计工具,但更大量的是它提供各种数学计算、统计计算的函数,从而使使用者能灵活机动的进行数据分析,甚至创造出符合需要的新的统计计算方法。 该语言的语法表面上类似 C,但在语义上是函数设计语言(functional programming language)的变种并且和Lisp 以及 APL有很强的兼容性。特别的是,它允许在"语言上计算"(computing on the language)。这使得它可以把表达式作为函数的输入参数,而这种做法对统计模拟和绘图非常有用。 R是一个免费的*软件,它有UNIX、LINUX、MacOS和WINDOWS版本,都是可以免费下载和使用的。在R主页那儿可以下载到R的安装程序、各种外挂程序和文档。在R的安装程序中只包含了8个基础模块,其他外在模块可以通过CRAN获得。 二、R语言 R是用于统计分析、绘图的语言和操作环境。R是属于GNU系统的一个*、免费、源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具。 R作为一种统计分析软件,是集统计分析与图形显示于一体的。它可以运行于UNIX,Windows和Macintosh的操作系统上,而且嵌入了一个非常方便实用的帮助系统,相比于其他统计分析软件,R还有以下特点: 1.R是*软件。这意味着它是完全免费,开放源代码的。可以在它的网站及其镜像中下载任何有关的安装程序、源代码、程序包及其源代码、文档资料。标准的安装文件身自身就带有许多模块和内嵌统计函数,安装好后可以直接实现许多常用的统计功能。[2] 2.R是一种可编程的语言。作为一个开放的统计编程环境,语法通俗易懂,很容易学会和掌握语言的语法。而且学会之后,我们可以编制自己的函数来扩展现有的语言。这也就是为什么它的更新速度比一般统计软件,如,SPSS,SAS等快得多。大多数最新的统计方法和技术都可以在R中直接得到。[2] 3. 所有R的函数和数据集是保存在程序包里面的。只有当一个包被载入时,它的内容才可以被访问。一些常用、基本的程序包已经被收入了标准安装文件中,随着新的统计分析方法的出现,标准安装文件中所包含的程序包也随着版本的更新而不断变化。在另外版安装文件中,已经包含的程序包有:base一R的基础模块、mle一极大似然估计模块、ts一时间序列分析模块、mva一多元统计分析模块、survival一生存分析模块等等.[2] 4.R具有很强的互动性。除了图形输出是在另外的窗口处,它的输入输出窗口都是在同一个窗口进行的,输入语法中如果出现错误会马上在窗口口中得到提示,对以前输入过的命令有记忆功能,可以随时再现、编辑修改以满足用户的需要。输出的图形可以直接保存为JPG,BMP,PNG等图片格式,还可以直接保存为PDF文件。另外,和其他编程语言和数据库之间有很好的接口。[2] 5.如果加入R的帮助邮件列表一,每天都可能会收到几十份关于R的邮件资讯。可以和全球一流的统计计算方面的专家讨论各种问题,可以说是全世界最大、最前沿的统计学家思维的聚集地.[2] R是基于S语言的一个GNU项目,所以也可以当作S语言的一种实现,通常用S语言编写的代码都可以不作修改的在R环境下运行。 R的语法是来自Scheme。R的使用与S-PLUS有很多类似之处,这两种语言有一定的兼容性。S-PLUS的使用手册,只要稍加修改就可作为R的使用手册。所以有人说:R,是S-PLUS的一个“克隆”。 但是请不要忘了:R是免费的(R is free)。R语言源代码托管在github,具体地址可以看参考资料。[3] 。 R语言的下载可以通过CRAN的镜像来查找。 R语言有域名为.cn的下载地址,有六个,其中两个由Datagurn,由 中国科学技术大学提供的。R语言Windows版,其中由两个下载地点是Datagurn和 USTC提供的。 三、stata Stata 是一套提供其使用者数据分析、数据管理以及绘制专业图表的完整及整合性统计软件。它提供许许多多功能,包含线性混合模型、均衡重复反复及多项式普罗比模式。用Stata绘制的统计图形相当精美。 新版本的STATA采用最具亲和力的窗口接口,使用者自行建立程序时,软件能提供具有直接命令式的语法。Stata提供完整的使用手册,包含统计样本建立、解释、模型与语法、文献等超过一万余页的出版品。 除此之外,Stata软件可以透过网络实时更新每天的最新功能,更可以得知世界各地的使用者对于STATA公司提出的问题与解决之道。使用者也可以透过Stata. Journal获得许许多多的相关讯息以及书籍介绍等。另外一个获取庞大资源的管道就是Statalist,它是一个独立的listserver,每月交替提供使用者超过1000个讯息以及50个程序。 四、PYTHON