Реализации для цикла событий в C / C ++, которые хороши в стеке вызовов

TL; DR

Какова лучшая реализация для цикла событий в C / C ++, который хорошо управляет стеком вызовов?

  • Зачем?
  • Бенчмарки / Сравнение?
  • Литература / Публикации / Документация?

Это простая концепция: ждать события, обрабатывать события, ждать новых событий.

Я оглядывался назад на некоторые старые проекты и наткнулся на простую (и довольно плохую) реализацию поисковой системы, и мое любопытство вызвало правильный способ сделать цикл событий.

В то время я сделал что-то вроде этого (очень) упрощенного примера:

int wait_for_query();
int handle_query();

int main(int argc, const char** argv) {
return wait_for_query();
}

int wait_for_query() {
// Do some stuff
return handle_query();
}

int handle_query() {
// Handle it
// if query is quit, return quit();
return wait_for_query();
}

int quit() {
return 0;
}

Эта реализация опирается на цепочку вызовов для достижения «цикла событий». Я использую кавычки, потому что, хотя это логически цикл событий, стек вызовов постоянно увеличивается и никогда не раскручивается:

                                            wait_for_query____...
/
handle_query_______/
/
wait_for_query_______/

Хотя он работает, он всегда добавляет новые стековые фреймы в стек и в конечном итоге, после достаточного количества событий, он вызовет Переполнение стека ошибка! (хаха так мета).

То, что я хочу, это что-то вроде этого:

                       handle_query           handle_query
/            \         /            \
wait_for_query_______/              \_______/              \_____...

Я всегда слышал, что ОС это просто while(true) Цикл, который прерывается, так что (поскольку моя ОС недавно не получила ошибку SO), вот что я подумал:

  • Заменить основной на:

    while(1)
    if (wait_for_query() == 0) break;
    return 0;
    
  • + Изменить handle_queryвернемся к 1

Но делает ли это на самом деле сделать его более эффективным в стеке? Насколько мне известно, while циклы (и циклы в целом) по-прежнему создают стековые фреймы на ассемблере (так как все они выполняются с помощью контекста / локальных переменных / и т.

Какова лучшая реализация для цикла событий в C / C ++, который хорошо управляет стеком вызовов?

  • Зачем?
  • Бенчмарки / Сравнение?
  • Литература / Публикации / Документация?

Заметки

Этот вопрос предполагает однопоточный цикл обработки событий. Распараллеленные ответы тоже приемлемы, но я подумал, что было бы слишком много спросить обо всем сразу;)

Огонь прочь

-2

Решение

Исходные решения принципиально сломанный. Событие петля выглядит примерно так:

while (q != QUITE) {
q = wait_for_query();
handle_query(q);
}

Это так просто. Что на самом деле согласуется с тем, что вы описали:

Это простая концепция: ждать события, обрабатывать события, ждать новых событий.

В исходном коде, семантически, обрабатывая событие, handle_query(), никогда не завершится, пока все будущие события также не будут завершены, рекурсивно, то есть ни одно событие не будет завершено. Что не то, что вы хотите.

Детализация может быть очень сложной, например, как вы получаете события? это блокирует или нет? как события отправляются? … так далее.

2

Другие решения

На самом деле, while не будет генерировать новые кадры стека сам по себе. Кадры стека создаются, когда call Инструкция выдается.

Если вы делаете handle_query вернуть 1 как вы упоминаете, тогда ваш цикл не будет увеличивать стек дальше, чем на два уровня (wait_query+handle_query) для каждого события оно обрабатывает:

                                  handle_query           handle_query
/            \         /            \
wait_for_query_______/              \_______/              \_____...
/
/
main_loop

Который выглядит как структура стека, которую вы искали.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector