通过eventfd在线程之间传输数据

小亚历山大·斯托克斯(Alexander Stocks Jr)

我希望通过eventfd在线程之间传输数据。因此,我编写了以下代码来满足我的需要。我的主机操作系统是openSUSE v12.3 64bit。

 #include "stdio.h"
 #include "unistd.h"
 #include "pthread.h"
 #include "sys/eventfd.h"
 #include "sys/epoll.h"
 #define nil NULL

 int efd = -1;

 void* read_thread(void* arg)   {

        int ret = 0;
    uint64_t count = 0;
    int ep_fd = -1;
    struct epoll_event events[10];

    (void)(arg);
    if (efd < 0) {
        printf("efd not inited.\n");
        return nil;
    }

    ep_fd = epoll_create(1024);
    if (ep_fd < 0) {
        perror("epoll_create fail: ");
        return nil;
    }

    {
        struct epoll_event read_event;

        read_event.events = EPOLLIN;
        read_event.data.fd = efd;

        ret = epoll_ctl(ep_fd, EPOLL_CTL_ADD, efd, &read_event);
        if (ret < 0) {
            perror("epoll ctl failed:");
            return nil;
        }
    }

    while (1) {
        ret = epoll_wait(ep_fd, events, 10, 5000);
        if (ret > 0) {
            int i = 0;
            for (i = 0; i < ret; i++) {
                if (events[i].events & (EPOLLHUP | EPOLLERR)) {
                    printf("epoll eventfd has epoll hup.\n");
                    break;
                } else if (events[i].events & EPOLLIN) {
                    int event_fd = events[i].data.fd;
                    ret = eventfd_read(event_fd, &count);
                    if (ret < 0) {
                        perror("read fail:");
                        break;
                    } else {
                        printf("read %llu\n", count);
                    }
                }
            }
        } else if (ret == 0) {
            break;
        } else {
            perror("epoll wait error:");
            break;
        }
    }

    close(ep_fd);
    return nil;
}

int main(int argc, char *argv[]) {

    pthread_t pid = 0;
    uint64_t count = 0;
    int ret = 0;
    int i = 0;

    efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
    if (efd < 0) {
        perror("eventfd failed.");
        return -1;
    }

    ret = pthread_create(&pid, NULL, read_thread, NULL);
    if (ret < 0) {
        perror("pthread create:");
        close(efd);
        return -2;
    }

    for (i = 0; i < 5; i++) {
        count = i + 1;
        ret = eventfd_write(efd, count);
        if (ret < 0) {
            perror("write event fd fail:");
            break;
        } else {
            printf("write %llu\n", count);
        }
    }

    sleep(3);

    pthread_join(pid, NULL);
    close(efd);
    efd = -1;

    return 0;
}

我认为eventfd的行为应该像管道。因此,程序的输出结果可能如下:

写入1读取1写入2读取2写入3读取3写入4读取4写入5读取5

但是,其实际结果是:

写1写2写3写4写5读15

或者

写入1写入2写入3写入4写入5读取1读取14

一些好人能告诉我为什么输出结果是输入结果的总和吗?

我无法通过线程之间的eventfd正确传输数据。我也不喜欢烟斗。如何在线程之间正确地一一传输数据?

JSON格式

eventfd使用内核维护的计数器,该计数器从提供给eventfd()的值开始。此计数器通过write()通过值'sent'递增,因此,如果您创建的eventfd的初始值为1,然后创建write()2,则读取的值为3。如果再写入()5 ,则read()的值为8,依此类推。

eventfd通常由事件驱动模式中的线程使用,但是您需要使用队列或其他容器来传递实际值,或检出signalfd(),该信号可用于通过sigqueue()接收附加到信号的数据。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

通过eventfd在线程之间传输数据

来自分类Dev

在线程之间传输函数调用

来自分类Dev

C ++-在线程之间传递数据

来自分类Dev

可以使用std :: atomic内存屏障在线程之间传输非原子数据吗?

来自分类Dev

在线程之间传递可变数据

来自分类Dev

在线程之间共享字典中的数据

来自分类Dev

如何在线程之间传递数据?

来自分类Dev

在线程之间发送数据的惯用方式是什么?

来自分类Dev

在线程之间共享数据并强制锁定

来自分类Dev

使用管道在线程之间发送数据

来自分类Dev

工作共享机制(在OpenMP中)是否在线程正在执行时在线程之间传输任务?

来自分类Dev

在线程之间传递对象

来自分类Dev

在线程之间移动向量

来自分类Dev

在线程之间共享mvar

来自分类Dev

在线程之间共享容器阵列

来自分类Dev

在线程之间共享变量的方法

来自分类Dev

在线程之间分配不均数

来自分类Dev

在线程之间发送盒装特征

来自分类Dev

pthreads在线程之间共享内存

来自分类Dev

在线程之间传递对象

来自分类Dev

在线程之间传递NSManagedObjectContext

来自分类Dev

火炬线程-在主线程和线程之间传输数据一次

来自分类Dev

与工作线程之间的回调之间的回调数据传输

来自分类Dev

多线程问题-在线程之间传递对象

来自分类Dev

为什么在线程之间切换比在进程之间切换和在它们之间共享数据要快?

来自分类Dev

flask会话变量是否在线程之间保持状态?

来自分类Dev

如何在线程之间发送变量/信息

来自分类Dev

使用Android Realm在线程之间进行读写

来自分类Dev

HINSTANCE在线程之间有效吗?