сопрограммы co_await не работают одновременно в консольном приложении - PullRequest
0 голосов
/ 09 января 2020

Я не понимаю вывод моего небольшого примера кода.

Когда я отлаживаю в коде MS C ++ / WinRT, я вижу вызов WINRT_TrySubmitThreadpoolCallback () и WINRT_CreateThreadpoolTimer (). Я думаю, что 3 выполнение g () должно происходить одновременно.

Этот код:

auto g() -> IAsyncAction {
    Log(L"Entering g()");
    co_await winrt::resume_after(1s);
    Log(L"Exiting g()");
}
auto f() -> IAsyncAction {
    Log(L"Entering f()");
    co_await winrt::resume_background();
    Log(L"First call to g()");
    co_await g();
    Log(L"Second call to g()");
    co_await g();
    Log(L"Third call to g()");
    co_await g();
    Log(L"Exiting f()");
}
auto main() -> int {
    init_apartment();
    f().get();
    return 0;
}

Выводит следующее (с префиксом ID потока):

24000   Entering f()
13160   First call to g()
13160   Entering g()
13160   Exiting g()
13160   Second call to g()
13160   Entering g()
13160   Exiting g()
13160   Third call to g()
13160   Entering g()
13160   Exiting g()
13160   Exiting f()

Он не запускает экземпляр g () одновременно. Не так ли?

У меня разговор об этом на Slack (Cpplang # coroutines), где многие люди любезно пытаются дать мне понять, почему мой пример кода работает так, как он работает. Хотя их объяснения не относятся к C ++ / WinRT c, я надеюсь получить здесь другой ответ.

Спасибо.

1 Ответ

0 голосов
/ 09 января 2020

Я думаю, что 3 выполнение g () должно происходить одновременно.

C ++ / WinRT интегрирует сопрограммы C ++ в модель программирования, чтобы обеспечить естественный способ совместного ожидания результата. Вы можете создать собственную Windows асинхронную операцию во время выполнения, написав сопрограмму. Сопрограмма - это функция, аналогичная любой другой, в которой вызывающая сторона блокируется до тех пор, пока функция не вернет к ней выполнение. Вы можете использовать оператор co_await, чтобы совместно ожидать результата любой функции, которая возвращает один из этих типов асинхронных операций.

Это означает, что когда вы вызываете функцию g (), оператор co_await будет ожидать операцию в g () метод для завершения, прежде чем продолжить. Так что поведение правильное. Более подробно вы можете обратиться к этому документу .

...