epoll_t类
epoll通常用于单线程读取多个串口的数据
#include <unistd.h>
#include <sys/epoll.h>
#include <mutex>
#include <functional>
#include <map>
using namespace std;
// 这里使用了mutex, map, 防止对象被移除后(移除后有可能就被销毁了),还回调
// ---------------------------------------------------------------------------
class epoll_t
{
private:
epoll_t();
epoll_t& operator=(const epoll_t& rhs) = delete;
epoll_t& operator=(const epoll_t&& rhs) = delete;
public:
static const epoll_t& self();
public:
bool add(int fd, function<void(int fd)> callback) const;
bool remove(int fd) const;
void wait() const;
private:
void map_callback(int fd, function<void(int fd)>& callback) const;
void unmap_callback(int fd) const;
void on_callback(int fd) const;
private:
int m_epfd;
mutable recursive_mutex m_mutex;
mutable map<int, function<void(int fd)>> m_fd_to_callback;
};
// 构造
// ---------------------------------------------------------------------------
epoll_t::epoll_t()
{
m_epfd = epoll_create(1024);
}
// 单例
// ---------------------------------------------------------------------------
const epoll_t& epoll_t::self()
{
static epoll_t instance;
return instance;
}
// 添加回调
// ---------------------------------------------------------------------------
bool epoll_t::add(int fd, function<void(int fd)> callback) const
{
map_callback(fd, callback);
epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = fd;
return epoll_ctl(m_epfd, EPOLL_CTL_ADD, fd, &ev) != -1;
}
// 移除回调
// ---------------------------------------------------------------------------
bool epoll_t::remove(int fd) const
{
unmap_callback(fd);
return epoll_ctl(m_epfd, EPOLL_CTL_DEL, fd, NULL) != -1;
}
// 等待数据
// ---------------------------------------------------------------------------
void epoll_t::wait() const
{
epoll_event ev[8];
int n = epoll_wait(m_epfd, ev, 8, -1);
for (int i = 0; i < n; i++)
{
on_callback(ev[i].data.fd);
}
}
// 映射callback
// ---------------------------------------------------------------------------
void epoll_t::map_callback(int fd, function<void(int fd)>& callback) const
{
unique_lock<recursive_mutex> lock(m_mutex);
m_fd_to_callback[fd] = callback;
}
// 取消映射callback
// ---------------------------------------------------------------------------
void epoll_t::unmap_callback(int fd) const
{
unique_lock<recursive_mutex> lock(m_mutex);
auto it = m_fd_to_callback.find(fd);
if (it != m_fd_to_callback.end())
{
m_fd_to_callback.erase(it);
}
}
// 回调
// -----------------------------------------------------------------------------------
void epoll_t::on_callback(int fd) const
{
unique_lock<recursive_mutex> lock(m_mutex);
auto it = m_fd_to_callback.find(fd);
if (it != m_fd_to_callback.end())
{
it->second(fd);
}
}
int main()
{
}