Linux进程/线程协作之eventfd

eventfd是linux的一个系统调用,为事件通知创建文件描述符。
eventfd()创建一个“eventfd对象”,这个对象能被用户空间应用用作一个事件等待/响应机制,靠内核去响应用户空间应用事件。这个对象包含一个由内核保持的无符号64位整型计数器。这个计数器由参数initval说明的值来初始化。
以下例子展示了在线程之间及fork()产生的进程之间的通信。

/* 创建线程之后主线程和子线程谁先运行是不确定的。
 * 通过一个eventfd在线程之间传递数据的好处是多个线程无需上锁就可以实现同步。
 * eventfd支持的最低内核版本为Linux 2.6.27,在2.6.26及之前的版本也可以使用eventfd,但是flags必须设置为0。
 * 函数原型:
 *     #include <sys/eventfd.h>
 *     int eventfd(unsigned int initval, int flags);
 * 参数说明:
 *      initval,初始化计数器的值。
 *      flags, EFD_NONBLOCK,设置socket为非阻塞。
 *             EFD_CLOEXEC,执行fork的时候,在父进程中的描述符会自动关闭,子进程中的描述符保留。
 * 场景:
 *     eventfd可以用于同一个进程之中的线程之间的通信。
 *     eventfd还可以用于同亲缘关系的进程之间的通信。
 *     eventfd用于不同亲缘关系的进程之间通信的话需要把eventfd放在几个进程共享的共享内存中(没有测试过)。
 */
#include <stdlib.h>
#include <stdio.h>
#include <sys/eventfd.h>
#include <pthread.h>
#include <memory.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>

int efd = -1;
//循环接收线程。
void * recv(void * pars) {
    int len = -1;
    uint64_t msg = 0;

    printf("Thread created!\n");
    while(1) {
        len = read(efd, &msg, sizeof(uint64_t)); //如果计数器为0则阻塞。
        printf("Current msg is %d\n", msg);
    }
}

int main(int argc, char ** argv) {
    pthread_t tid;
    pid_t fpid;
    int len = -1;
    uint64_t item = 1;
    int i = 0;

    efd = eventfd(0, 0);
    if(efd == -1) {
        printf("Error! Fail to create event fd.\n");
    } else {
        printf("OK! Create event fd is %d\n", efd);
    }
    fpid = fork();
    if(fpid > 0) {  //父进程接收消息(父进程同时也发送消息。)
        pthread_create(&tid, NULL, recv, NULL);
    }

    //循环发送。
    while(1) {
        sleep(1);
        len = write(efd, &item, sizeof(uint64_t)); //如果写sizeof(unsigned int)则参数错误。必须传8。
                                    //如果计数器达到0xfffffffe,则阻塞。
        if(len != sizeof(uint64_t)) {
            printf("Error! Fail to write event fd, errno: %d,errmsg: %s\n"
                    ,errno, strerror(errno));
        }else {
            printf("Success to write.\n");
        }
    }
    pthread_exit(0);
    return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值