什么是eventfd

eventfd是Linux 2.6提供的一种系统调用,它可以用来实现事件通知。eventfd包含一个由内核维护的64位无符号整型计数器,创建eventfd时会返回一个文件描述符,进程可以通过对这个文件描述符进行read/write来读取/改变计数器的值,从而实现进程间通信。

创建eventfd

eventfd的创建是通过eventfd函数实现的,返回值即是该eventfd所对应的文件描述符,函数的原型如下所示:

创建eventfd时它所对应的64位计数器的初始值;

eventfd文件描述符的标志,可由三种选项组成:EFD_CLOEXEC、EFD_NONBLOCK和EFD_SEMAPHORE。

  • EFD_CLOEXEC表示返回的eventfd文件描述符在fork后exec其他程序时会自动关闭这个文件描述符;
  • EFD_NONBLOCK设置返回的eventfd非阻塞;
  • EFD_SEMAPHORE表示将eventfd作为一个信号量来使用。

读eventfd

既然eventfd是一个文件描述符,那么对其进行读取就是使用read函数了,不过对于eventfd调用read函数也有需要注意的地方,man手册有如下描述:

从上面描述中可以知道以下几点:

  • read函数会从eventfd对应的64位计数器中读取一个8字节的整型变量;
  • read函数设置的接收buf的大小不能低于8个字节,否则read函数会出错,errno为EINVAL;
  • read函数返回的值是按小端字节序的;
  • 如果eventfd设置了EFD_SEMAPHORE,那么每次read就会返回1,并且让eventfd对应的计数器减一;如果eventfd没有设置EFD_SEMAPHORE,那么每次read就会直接返回计数器中的数值,read之后计数器就会置0。不管是哪一种,当计数器为0时,如果继续read,那么read就会阻塞(如果eventfd没有设置EFD_NONBLOCK)或者返回EAGAIN错误(如果eventfd设置了EFD_NONBLOCK)。

写eventfd

同样,对eventfd进行写操作使用的是write函数,在Man手册中也有相应的描述:

从上面描述中可以知道:

  • 在没有设置EFD_SEMAPHORE的情况下,write函数会将发送buf中的数据写入到eventfd对应的计数器中,最大只能写入0xffffffffffffffff,否则返回EINVAL错误;

  • 在设置了EFD_SEMAPHORE的情况下,write函数相当于是向计数器中进行“添加”,比如说计数器中的值原本是2,如果write了一个3,那么计数器中的值就变成了5。如果某一次write后,计数器中的值超过了0xfffffffffffffffe(64位最大值-1),那么write就会阻塞直到另一个进程/线程从eventfd中进行了read(如果write没有设置EFD_NONBLOCK),或者返回EAGAIN错误(如果write设置了EFD_NONBLOCK)。

  • 除此之外,eventfd还支持select和poll,与一般的读写描述符相类似,这里就不多说了,如下所示:

使用例子

现在写一个简单的例程,在父子进程中利用eventfd进行通信,如下所示:

#include <unistd.h>
#include <iostream>
#include <sys/wait.h>
#include <sys/eventfd.h>
#include <errno.h>
#include <stdio.h>
using namespace std;int main()
{int evfd = eventfd(10,0);uint64_t wdata = 0;uint64_t rdata = 0;if(read(evfd,&rdata,8) == -1){perror(NULL);if(errno!=EAGAIN)return 0;}cout<<"Init read : "<<rdata<<endl;  //读计数器初始值wdata = 20;if(write(evfd,&wdata,8) == -1) //父进程写20{perror(NULL);return 0;}cout<<"parent write : "<<wdata<<endl;if(fork() == 0){wdata = 30;if(read(evfd,&rdata,8) == -1) //子进程读计数器{perror(NULL);return 0;}cout<<"child read : "<<rdata<<endl;if(write(evfd,&wdata,8) == -1)  //子进程写30{perror(NULL);return 0;}cout<<"child write : "<<wdata<<endl;exit(0);     }wait(NULL);if(read(evfd,&rdata,8) == -1)   //父进程读计数器{perror(NULL);return 0;}cout<<"parent read : "<<rdata<<endl;return 0;
}

运行结果如下:

linux进程(线程间)间通信-eventfd相关推荐

  1. Linux进程线程学习笔记:运行新程序

    Linux进程线程学习笔记:运行新程序 周银辉 在上一篇中我们说到,当启动一个新进程以后,新进程会复制父进程的大部份上下文并接着运行父进程中的代码,如果我们使新进程不运行原父进程的代码,转而运行另外一 ...

  2. 【Linux进程/线程间通信】实现荔枝派zero与电脑串口通信

    本文采取两种方法来实现: <1>System V IPC 的消息队列(message queue) <2>有名信号量/灯的同步操作(semaphore) 一.System V ...

  3. 32位linux进程线程在内存中的样子

    1.线程诞生史 1.1 线程诞生的原因 早期是没有线程概念的,只有进程的概念,操作系统以进程为调度单位.--可以这么来理解:早期进程相当于现在的单线程的进程(只有一个线程的进程,创建进程时,里面有一个 ...

  4. linux进程线程协程的区别,进程和线程、协程的区别

    现在多进程多线程已经是老生常谈了,协程也在最近几年流行起来.python中也有协程库,tornado中也用了gevent封装好的协程.本文主要介绍进程.线程和协程三者之间的区别. 一.概念 1.进程 ...

  5. 观察Linux进程 线程的异步并发执行,操作系统linux版实验报告.doc

    操作系统linux版实验报告.doc (29页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 操作系统实验报告(Linux版)网络142 ...

  6. linux进程管理 实现管道通信,Linux进程管理(二)管道通信 · lww’s Blog

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 实验内容试验阻塞型读写过程中的各种情况 试验阻塞型读写过程中的各种情况 利用Posix信号量机制实现进程间对管道的互斥访 ...

  7. linux进程线程视频百度云,linux 进程线程时间片

    aero 回复于:2003-08-10 21:01:44 偶觉得,已经不菜了. 如果你菜,那偶就还是鸟蛋了. coolhome 回复于:2003-08-10 20:27:00 [code:1:334e ...

  8. linux进程线程同步之 - POSIX线程互斥锁

    POSIX线程互斥锁 使用范围:线程同步 本文转自:http://blog.csdn.net/jiebaoabcabc/article/details/37914769 一.函数介绍 1.初始化互斥锁 ...

  9. linux 进程线程拓展

    依次参考: 多线程和多进程的区别(小结) Linux内核源代码分析--fork()原理&多进程网络模型 Linux写时拷贝技术(copy-on-write) linux内核 do_fork 函 ...

  10. linux 进程线程限制,LINUX停每进程限制线程数量

    参考: http://stackoverflow.com/questions/344203/maximum-number-of-threads-per-process-in-linux 理论上相关限制 ...

最新文章

  1. usleep延时0.毫秒_LabVIEW从0到1系列视频培训_第4讲全集_操作例程说明
  2. 第一次冲刺个人博客07
  3. 两种方法动态获得ABAP类的class attribute的值
  4. Spring-framework应用程序启动loadtime源码分析笔记(二)——@Transactional
  5. 日志框架介绍(SLF4J及其使用)
  6. J2EE五层架构概念[转+整理]
  7. c++ primer5 第一章练习题答案 尚未完成 后续补充(基本已经完结)
  8. python最简单的游戏源代码_Python 练习: 简单角色游戏程序
  9. css定位position,absolute relative两种情况下,top,left,right,bottom的区别
  10. xgboost算模型输出的解释
  11. 群晖nas存储系统原理_群晖NAS入门教程第四节:群晖存储空间管理员功能和磁盘阵列类型的简介...
  12. 【Windows XP系统壁纸设置有哪些技巧】
  13. 大致看了下伍德里奇的《计量经济学导论》
  14. mPEG-Pyrene,甲氧基聚乙二醇芘丁酸
  15. 机器学习及深度学习技术在海洋科学方面的应用
  16. 岭南的一艘 “海盗船” 出海时扬起了单机游戏的帆
  17. linux mmc驱动框架,Linux mmc framework2:基本组件之mmc
  18. Java模式参考大全
  19. iPhone微信网页数字识别成了电话
  20. 重学React基础知识整理(二)

热门文章

  1. 零元学Expression Blend 4 - Chapter 9 用实例了解布局容器系列-「Canvas」
  2. MFC 线程创建方式
  3. JDBC在Java Web中的应用——分页查询
  4. java基础----java调用oracle存储过程(转)
  5. 我为什么不喜欢网赚和SEO
  6. uploadify 3.1 的修改
  7. Apache并发请求数及其TCP连接状态故障排除
  8. Tomcat优化之配置线程池高并发连接
  9. 3.中小型企业通用自动化运维架构 -- Ansible playbook
  10. 5.被动回复用户消息