zoukankan      html  css  js  c++  java
  • Epoll的使用例子

    本篇文章在上一篇的基础上,使用 epoll  实现了一个事件监听和回调处理的模块。如何编写一个使用该模块的例子呢? 监测什么类型的fd,监测什么类型的事件,监测到事件以后需要做什么?后来可以看看如何将该模块与socket , 回调函数, 线程池联系起来。

    #include<sys/epoll.h> // epoll_create, epoll_ctl, epoll_wait
    #include <mutex> // std::mutex
    #include <functional> // std::function
    #include <iostream> 
    #include <memory> // std::unique_ptr
    #include <unistd.h> // close
    
    class Epoll{
    public:
       class ActiveEvents {
          public: 
            ActiveEvents( int num, const struct epoll_event* events):
                    num_( num ),
                    events_( events )
                    {
                    }
            int num() const { return num_; }
            const struct epoll_event* events() const { return events_; }
    
          private:
             int num_;
             const struct epoll_event* events_;
       };
    
       Epoll();
       ~Epoll();
    
       int AddMonitorReadableEvent( int fd );
       int AddMonitorWritableEvent( int fd );
       int DeleteMonitoringEvent( int fd );
       int ModifyMonitorEvent( int fd , int status );
    
       void StartPolling();
       void HandleEvents( int num, const struct epoll_event* events );
       void Stop();
    
       using EpollAwakeCallBack = std::function< void(const ActiveEvents*) > ;
       void SetAwakeCallBack( EpollAwakeCallBack* cb ); // 设置事件处理回调函数
    
    private :
       int Add_Event( int fd, int event );  // 封装 epoll_ctl, 使函数语义看起来更明确
       int Delete_Event( int fd, int event ); 
       int Modify_Event( int fd, int event );
    
       int epollfd_;
       std::unique_ptr< EpollAwakeCallBack > awake_cb_ ;
       static const int fd_size_; // 最多能处理的fd个数
       std::mutex awake_cb_mutex_; // 由于使用std::unique_ptr保存回调函数指针,设置回调函数时需要加锁
       std::mutex mutex_;
    };
    
    const int  Epoll::fd_size_  = 100 ;
    
    Epoll::Epoll() {
        epollfd_ = epoll_create(fd_size_);
        std::cout << "epollfd = " << epollfd_ << std::endl;
    }
    
    Epoll::~Epoll() {
        std::cout << "deleting epoll" << std::endl;
        close(epollfd_);
    }
    
    void Epoll::StartPolling() {
        const int EPOLLEVENTS = 100;
        struct epoll_event events[EPOLLEVENTS];
        while (1) {
            auto ret = epoll_wait(epollfd_, events, EPOLLEVENTS, -1);
            std::cout << "awakening " << ret << std::endl;
            HandleEvents(ret, events);
        }
    }
    
    void Epoll::HandleEvents(int num, const struct epoll_event* events) {
        ActiveEvents active_events(num, events);
        std::unique_lock<std::mutex> lock(awake_cb_mutex_);
        if (awake_cb_) {
            (*awake_cb_)(&active_events);
        }
    }
    
    void Epoll::SetAwakeCallBack(EpollAwakeCallBack* cb) {
        std::unique_lock<std::mutex> lock(awake_cb_mutex_);
        awake_cb_.reset(cb);
    }
    
    int Epoll::AddMonitorReadableEvent(int fd) {
        // TODO: Are epoll_wait and epoll_ctl thread-safe?
        std::unique_lock<std::mutex> lock(mutex_);
        return Add_Event(fd, EPOLLIN | EPOLLONESHOT);
    }
    
    int Epoll::AddMonitorWritableEvent(int fd) {
        std::unique_lock<std::mutex> lock(mutex_);
        return Add_Event(fd, EPOLLOUT | EPOLLONESHOT);
    }
    
    int Epoll::DeleteMonitoringEvent(int fd) {
        std::unique_lock<std::mutex> lock(mutex_);
        return Delete_Event(fd, EPOLLIN | EPOLLONESHOT);
    }
    
    int Epoll::ModifyMonitorEvent(int fd, int status) {
        std::unique_lock<std::mutex> lock(mutex_);
        return Modify_Event(fd, status);
    }
    
    int Epoll::Add_Event(int fd, int event) {
        struct epoll_event ev;
        ev.events = event;
        ev.data.fd = fd;
        int ret = epoll_ctl(epollfd_, EPOLL_CTL_ADD, fd, &ev);
        return ret;
    }
    
    int Epoll::Delete_Event(int fd, int event) {
        struct epoll_event ev;
        ev.events = event;
        ev.data.fd = fd;
        int ret = epoll_ctl(epollfd_, EPOLL_CTL_DEL, fd, &ev);
        return ret;
    }
    
    int Epoll::Modify_Event(int fd, int event) {
        struct epoll_event ev;
        ev.events = event;
        ev.data.fd = fd;
        int ret = epoll_ctl(epollfd_, EPOLL_CTL_MOD, fd, &ev);
        return ret;
    }
    
    
    int main(){
        Epoll a;
        return 0;
    }
  • 相关阅读:
    学习中的坑
    友链
    CF1131E String Multiplication 题解
    CF438E The Child and Binary Tree 题解
    [WC2005]友好的生物题解
    [IOI2016]shortcut 题解
    CF911F [Tree Destruction] 题解
    状压dp技巧之轮廓线 hdu1400/poj2411acwing291 蒙德里安的梦想
    TG-WC2021 笔记
    拯救世界2题解
  • 原文地址:https://www.cnblogs.com/zengtx/p/11933749.html
Copyright © 2011-2022 走看看