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字节的整数在计数器A上,如果A的值达到0xfffffffffffffffe时,就会阻塞(在阻塞模式下),直到A的值被read。阻塞和非阻塞情况同上面read一样。

 

下面是man里面的进程间通信的例子:

#include <sys/eventfd.h>

#include <unistd.h>

#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[])

{

              intefd, j;

              uint64_tu;

              ssize_ts;

 

              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()) {

                            case0:

                                          for(j = 1; j < argc; j++) {

                                                        printf("Childwriting %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("Childcompleted write loop\n");

 

                                          exit(EXIT_SUCCESS);

 

                            default:

                                          sleep(2);

 

                                          printf("Parentabout to read\n");

                                          s= read(efd, &u, sizeof(uint64_t));

                                          if(s != sizeof(uint64_t))

                                                   handle_error("read");

                                          printf("Parentread %llu (0x%llx) from efd\n",

                                                                                    (unsignedlong long) u, (unsigned long long) u);

                                          exit(EXIT_SUCCESS);

 

                            case-1:

                                          handle_error("fork");

              }

}

 

二次运行结果:

xtx@xtx-desktop:~/self-dep$ ./t_eventfd 1 23 4 5

Child writing 1 to efd

Child writing 2 to efd

Child writing 3 to efd

Child writing 4 to efd

Child writing 5 to efd

Child completed write loop

Parent about to read

Parent read 15 (0xf) from efd

xtx@xtx-desktop:~/self-dep$ ./t_eventfd 1 23

Child writing 1 to efd

Child writing 2 to efd

Child writing 3 to efd

Child completed write loop

Parent about to read

Parent read 6 (0x6) from efd

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值