redis中io复用之evport

从redis中的ae.c中可以知道目前复用io的方式有下面四种
#ifdef HAVE_EVPORT
#include "ae_evport.c"
#else
    #ifdef HAVE_EPOLL
    #include "ae_epoll.c"
    #else
        #ifdef HAVE_KQUEUE
        #include "ae_kqueue.c"
        #else
        #include "ae_select.c"
        #endif
    #endif
#endif
即复用io的四种方式分别是evport->epoll->kqueue->select。其执行的效率也是从高到低
我们首先看看evport是如何使用的。evport的实现在ae_evport.c中
其使用的步骤如下:
1:首先通过port_create() 来申请一个port
static int aeApiCreate(aeEventLoop *eventLoop) {
    int i;
	#申请结构体
    aeApiState *state = zmalloc(sizeof(aeApiState));
    if (!state) return -1;
	#通过port_create() 来申请一个port
    state->portfd = port_create();
    if (state->portfd == -1) {
        zfree(state);
        return -1;
    }

    return 0;
}
2:通过port_assocoate关联要要监控的fd
static int aeApiAssociate(const char *where, int portfd, int fd, int mask) {
    int events = 0;
    int rv, err;
	#从这里知道目前只有读和写这两个事件
    if (mask & AE_READABLE)
        events |= POLLIN;
    if (mask & AE_WRITABLE)
        events |= POLLOUT;


	#通过port_assocoate关联要要监控的fd
    rv = port_associate(portfd, PORT_SOURCE_FD, fd, events,
        (void *)(uintptr_t)mask);
  
    return rv;
}
2:通过port_getn开始监控fd的io事件
static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
    aeApiState *state = eventLoop->apidata;
    struct timespec timeout, *tsp;
    int mask, i;
    uint_t nevents;
    port_event_t event[MAX_EVENT_BATCHSZ];


    nevents = 1;
    if (port_getn(state->portfd, event, MAX_EVENT_BATCHSZ, &nevents,
        tsp) == -1 && (errno != ETIME || nevents == 0)) {
        if (errno == ETIME || errno == EINTR)
            return 0;

        /* Any other error indicates a bug. */
        perror("aeApiPoll: port_get");
        abort();
    }

    state->npending = nevents;
	#port_getn正常返回,表示监控到了io的read或者write事件
    for (i = 0; i < nevents; i++) {
            mask = 0;
			#根据返回event中的flag来区分是读事件还是写事件
            if (event[i].portev_events & POLLIN)
                mask |= AE_READABLE;
            if (event[i].portev_events & POLLOUT)
                mask |= AE_WRITABLE;
			#更新eventLoop 中监控到的io事件中的fd和mask
            eventLoop->fired[i].fd = event[i].portev_object;
            eventLoop->fired[i].mask = mask;


    }

    return nevents;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值