linux进程通信教程,Linux进程间通信-eventfd

Linux进程间通信-eventfd

eventfd是linux 2.6.22后系统提供的一个轻量级的进程间通信的系统调用,eventfd通过一个进程间共享的64位计数器完成进程间通信,这个计数器由在linux内核空间维护,用户可以通过调用write方法向内核空间写入一个64位的值,也可以调用read方法读取这个值。

新建

创建一个eventfd对象,或者说打开一个eventfd的文件,类似普通文件的open操作。

该对象是一个内核维护的无符号的64位整型计数器。初始化为initval的值。

#include

int eventfd(unsigned int initval, int flags);

flags可以以下三个标志位的OR结果:

EFD_CLOEXEC : fork子进程时不继承,对于多线程的程序设上这个值不会有错的。

EFD_NONBLOCK: 文件会被设置成O_NONBLOCK,读操作不阻塞。若不设置,一直阻塞直到计数器中的值大于0。

EFD_SEMAPHORE : 支持 semophore 语义的read,每次读操作,计数器的值自减1。

读操作

读取计数器中的值。

typedef uint64_t eventfd_t;

int eventfd_read(int fd, eventfd_t *value);

如果计数器中的值大于0:

设置了 EFD_SEMAPHORE 标志位,则返回1,且计数器中的值也减去1。

没有设置 EFD_SEMAPHORE 标志位,则返回计数器中的值,且计数器置0。

如果计数器中的值为0:

设置了 EFD_NONBLOCK 标志位就直接返回-1。

没有设置 EFD_NONBLOCK 标志位就会一直阻塞直到计数器中的值大于0。

写操作

向计数器中写入值。

int eventfd_write(int fd, eventfd_t value);

如果写入值的和小于0xFFFFFFFFFFFFFFFE,则写入成功

如果写入值的和大于0xFFFFFFFFFFFFFFFE

设置了 EFD_NONBLOCK 标志位就直接返回-1。

如果没有设置 EFD_NONBLOCK 标志位,则会一直阻塞直到read操作执行

关闭

#include

int close(int fd);

示例

示例1-一读一写:

#include

#include

#include

int main() {

int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);

eventfd_write(efd, 2);

eventfd_t count;

eventfd_read(efd, &count);

std::cout << count << std::endl;

close(efd);

}

上述程序主要做了如下事情:

创建事件,初始计数器为0;

写入计数2;

读出计数2

关闭事件

示例2-多读多写:

#include

#include

#include

int main() {

int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);

eventfd_write(efd, 2); // 写入2,计数器为2

eventfd_write(efd, 3); // 写入3, 计数器为2 + 3 = 5

eventfd_write(efd, 4); // 写入3, 计数器为5 + 4 = 9

eventfd_t count;

int read_result = eventfd_read(efd, &count);

std::cout << "read_result=" << read_result << std::endl; // 0

std::cout << "count=" << count << std::endl; // count = 9

read_result = eventfd_read(efd, &count);

std::cout << "read_result=" << read_result << std::endl; // -1,返回失败

std::cout << "count=" << count << std::endl; // count = 9,为原来的值

close(efd);

}

示例3-EFD_SEMAPHORE标志位的作用:

#include

#include

#include

int main() {

int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC | EFD_SEMAPHORE);

eventfd_write(efd, 2); // 写入2,计数器为2

eventfd_t count;

int read_result = eventfd_read(efd, &count); // count = 1,计数器自减1,为1

std::cout << "read_result=" << read_result << std::endl; // 0

std::cout << "count=" << count << std::endl; // 1

read_result = eventfd_read(efd, &count); // count = 1,计数器自减1,为0

std::cout << "read_result=" << read_result << std::endl; // 0

std::cout << "count=" << count << std::endl; // 1

read_result = eventfd_read(efd, &count); // 读取失败

std::cout << "read_result=" << read_result << std::endl; // -1,读取失败

std::cout << "count=" << count << std::endl; // 1

close(efd);

}

可以看到设置了EFD_SEMAPHORE后,每次读取到的值都是1,且read后计数器也递减1。

微信公共号

NFVschool,关注最前沿的网络技术。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值