Administrator
发布于 2023-10-04 / 7 阅读 / 0 评论 / 0 点赞

10月4日

11:00起床

11:30-12;00

14:00学习

GitHub - chaixiang2002/cppserver (githubfast.com)

typedef union epoll_data {
  void *ptr;
  int fd;
  uint32_t u32;
  uint64_t u64;
} epoll_data_t;
struct epoll_event {
  uint32_t events;	/* Epoll events */
  epoll_data_t data;	/* User data variable */
} __EPOLL_PACKED;

epoll_event.data是一个union,可以是一个指针、一个fd、一个u32、一个u64

class Channel{
private:
    Epoll *ep;
    int fd;
    uint32_t events;
    uint32_t revents;
    bool inEpoll;
};
  • events表示希望监听这个文件描述符的哪些事件

  • revents表示在epoll返回该Channel时文件描述符正在发生的事件

  • inEpoll表示当前Channel是否已经在epoll红黑树中

如果我们希望监听该Channel上发生的读事件,需要调用一个enableReading函数:

void Channel::enableReading(){
    events = EPOLLIN | EPOLLET;
    ep->updateChannel(this);
}

可以看到该函数做了两件事,将要监听的事件events设置为读事件并采用ET模式,然后在ep指针指向的Epoll红黑树中更新该ChannelupdateChannel函数的实现如下:

void Epoll::updateChannel(Channel *channel){
    int fd = channel->getFd();  //拿到Channel的文件描述符
    struct epoll_event ev;
    bzero(&ev, sizeof(ev));
    ev.data.ptr = channel;
    ev.events = channel->getEvents();   //拿到Channel希望监听的事件
    if(!channel->getInEpoll()){
        errif(epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1, "epoll add error");//添加Channel中的fd到epoll
        channel->setInEpoll();
    } else{
        errif(epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev) == -1, "epoll modify error");//已存在,则修改
    }
}

事件驱动???传统的请求驱动模型?

事件的捕获、通信、处理和持久保留是解决方案的核心结构。libevent就是一个著名的C语言事件驱动库。


评论