Astellar
24.06.2010, 21:30
Дело было вечером, делать было нечего...
Решил я подробнее посмотреть на их использование в ядре. И не зря, сразу нашёл к чему придраться.
#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL)
ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true);
#else
ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true);
#endif
Это код из realmd. Вопрос один. Почему здесь используется ACE_TP_Reactor? Он специально разрабатывался для работы в пуле потоков, т.е. способен выполнять функцию run_reactor_event_loop параллельно, без боязни возникновения коллизий. Для поддержания подобного механизма работы, этот реактор накормлен дополнительными блокировками, в результате чего стал более неповоротливым.
И как мы его используем? Мы не создаем пул потоков. Мы продолжаем использовать его как обычный ACE_Select_Reactor, впустую тратя ресурсы на блокировки и прочее.
Использование ACE_TP_Reactor "по ГОСТу" выглядит следующим образом (внимание, не полный код).
static ACE_THR_FUNC_RETURN event_loop(void *arg)
{
ACE_Reactor *reactor = static_cast<ACE_Reactor*>(arg);
// No-op for TP reactor, but useful for others
reactor->owner(ACE_Thread::self());
reactor->run_reactor_event_loop();
}
void main(int, char **)
{
ACE_Reactor::instance
(new ACE_Reactor(new ACE_TP_Reactor, 1), 1);
ACE_Thread_Manager::instance()->spawn_n
(reactor_thread_num, event_loop, ACE_Reactor::instance());
return ACE_Thread_Manager::instance()->wait();
}
P.S. Вообще я проводил сравнение производительности реакторов под Linux. По итогам этого сравнения лидирует ACE_Select_Reactor с приличным отрывом, а отнюдь не Dev Poll. Могу выложить в эту тему результаты, но там реально много буковок получится.
Решил я подробнее посмотреть на их использование в ядре. И не зря, сразу нашёл к чему придраться.
#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL)
ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true);
#else
ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true);
#endif
Это код из realmd. Вопрос один. Почему здесь используется ACE_TP_Reactor? Он специально разрабатывался для работы в пуле потоков, т.е. способен выполнять функцию run_reactor_event_loop параллельно, без боязни возникновения коллизий. Для поддержания подобного механизма работы, этот реактор накормлен дополнительными блокировками, в результате чего стал более неповоротливым.
И как мы его используем? Мы не создаем пул потоков. Мы продолжаем использовать его как обычный ACE_Select_Reactor, впустую тратя ресурсы на блокировки и прочее.
Использование ACE_TP_Reactor "по ГОСТу" выглядит следующим образом (внимание, не полный код).
static ACE_THR_FUNC_RETURN event_loop(void *arg)
{
ACE_Reactor *reactor = static_cast<ACE_Reactor*>(arg);
// No-op for TP reactor, but useful for others
reactor->owner(ACE_Thread::self());
reactor->run_reactor_event_loop();
}
void main(int, char **)
{
ACE_Reactor::instance
(new ACE_Reactor(new ACE_TP_Reactor, 1), 1);
ACE_Thread_Manager::instance()->spawn_n
(reactor_thread_num, event_loop, ACE_Reactor::instance());
return ACE_Thread_Manager::instance()->wait();
}
P.S. Вообще я проводил сравнение производительности реакторов под Linux. По итогам этого сравнения лидирует ACE_Select_Reactor с приличным отрывом, а отнюдь не Dev Poll. Могу выложить в эту тему результаты, но там реально много буковок получится.