eventfd函数

从Linux 2.6.27版本开始,新增了不少系统调用,其中包括eventfd,它的主要是用于进程或者线程间的通信(如通知/等待机制的实现)。

 

函数原型:      

#include <sys/eventfd.h>

int eventfd(unsigned int initval, intflags);

参数解释:

如果是2.6.26或之前版本的内核,flags 必须设置为0。

Flags支持一下标志位:

EFD_NONBLOCK        类似于使用O_NONBLOCK标志设置文件描述符。

EFD_CLOEXEC          类似open以O_CLOEXEC标志打开, O_CLOEXEC 应该表示执行exec()时,之前通过open()打开的文件描述符会自动关闭测试时,在open()之后,调用一下exec(),在新的进程中检测描述符是否已经关闭

Initval:初始化计数器值,该值(暂时取名为A)保存在内核。

函数返回一个文件描述符,与打开的其他文件一样,可以进行读写操作。

Read:如果计数器A的值不为0时,读取成功,获得到该值。

         如果A的值为0,非阻塞模式时,会直接返回失败,并把error置为EINVAL

              如果为阻塞模式,一直会阻塞到A为非0为止。

Write:将缓冲区写入的8字节整形值加到内核计数器上,即会增加8字节的整数在计数器A上,如果A的值达到0xfffffffffffffffe时,就会阻塞(在阻塞模式下),直到A的值被read。阻塞和非阻塞情况同上面read一样。


程序实例:
  1. #include <sys/eventfd.h>  
  2. #include <unistd.h>  
  3. #include <stdlib.h>  
  4. #include <stdio.h>  
  5. #include <stdint.h>             /* Definition of uint64_t */  
  6.   
  7. #define handle_error(msg) \  
  8.    do { perror(msg); exit(EXIT_FAILURE); } while (0)  
  9.   
  10. int  
  11. main(int argc, char *argv[])  
  12. {  
  13.    uint64_t u;  
  14.       
  15.    int efd = eventfd(10, 0);  
  16.    if (efd == -1)  
  17.        handle_error("eventfd");  
  18.      
  19.    int ret = fork();  
  20.    if(ret == 0)  
  21.    {  
  22.        for (int j = 1; j < argc; j++) {  
  23.            printf("Child writing %s to efd\n", argv[j]);  
  24.            u = atoll(argv[j]);  
  25.            ssize_t s = write(efd, &u, sizeof(uint64_t));  
  26.            if (s != sizeof(uint64_t))  
  27.                handle_error("write");  
  28.        }  
  29.        printf("Child completed write loop\n");  
  30.   
  31.        exit(EXIT_SUCCESS);  
  32.    }  
  33.    else  
  34.    {  
  35.        sleep(2);  
  36.   
  37.        ssize_t s = read(efd, &u, sizeof(uint64_t));  
  38.        if (s != sizeof(uint64_t))  
  39.            handle_error("read");  
  40.        printf("Parent read %llu from efd\n",(unsigned long long)u);  
  41.        exit(EXIT_SUCCESS);  
  42.    }  
  43. }  

运行结果:
比较简单,不做过解释。子进程写入命令行中传入的参数,父进程读取其中计数器的值。

运行结果:

  1. ./eventfd 10 20 30  
  2. Child writing 10 to efd  
  3. Child writing 20 to efd  
  4. Child writing 30 to efd  
  5. Child completed write loop  
  6. Parent read 70 from efd  
命令行传入的是10、20、30其和应为60,为啥读取的是70呢?请看15行调用eventfd时第一个参数是10,这个参数是创建eventfd时初始化计数器的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值