Я реализую асинхронный шаблон Reactor в C ++, основанный на Epoll.
Сначала мы зарегистрируем файловый дескриптор в Reactor, вызвав функцию
template<typename Handle>
void Reactor::register(int descriptor, Handle handle){
//add this descriptor to epoll for monitoring
//store this handle with the key is the descriptor
}
И тогда вызывается метод hand_events, который выполняется вечно
void Reactor::handle_events(){
epoll_wait(..)
for(event in events){
//call the handle corresponding to the file descriptor return from epoll
//event.data.fd ==> handle
handle(...)
}
}
Мой вопрос, как организовать модель хранения в этой ситуации: хранить дескриптор, и отображение между дескриптором файла и дескриптором (есть ли подходящий шаблон для него)
Надеюсь увидеть ваш ответ!
Если все обработчики имеют одинаковую подпись, то с помощью std::function
в std::unordered_map
может быть достаточно.
std::unordered_map<int, std::function<void(int)>> fdmap;
Затем хранить как
fdmap[descriptor] = handle;
И просто позвони как
fdmap[event.data.fd](event.data.fd);
Конечно, в обработчике событий вы хотите убедиться, что отображение на самом деле содержит дескриптор файла.
Вы должны иметь возможность использовать разные подписи, если вы используете std::bind
при вызове вашей регистрационной функции:
my_reactor.register(fd, std::bind(my_handler, _1, another_argument, a_third_argument));
Затем, когда диспетчер событий вызывает вашу функцию-обработчик событий, это все равно, что вызывать ее с первым аргументом в качестве дескриптора и другими аргументами со значениями, которые вы передаете им в std::bind
вызов.
Других решений пока нет …