В этом последнем С++ TS: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4628.pdf, и на основе понимания поддержки языка С# async/await мне интересно что такое "контекст выполнения" (терминология, заимствованная из С#) сопрограмм С++?
Мой простой тестовый код в Visual С++ 2017 RC показывает, что сопрограммы, как представляется, всегда выполняются в потоке пула потоков, и разработчику приложения не уделяется мало внимания, в котором контекст потоковой передачи может выполняться сопрограммами - например, Может ли приложение заставлять все сопрограммы (с кодом сгенерированного машинного кода компилятора) выполняться только в основном потоке, без привлечения потока нитей потока?
В С# SynchronizationContext - это способ указать "контекст", где все "половинки" coroutine (компилятор сгенерированный код конечного автомата) будут размещены и выполнены, как показано в этом сообщении: https://blogs.msdn.microsoft.com/pfxteam/2012/01/20/await-synchronizationcontext-and-console-apps/, а текущая реализация coroutine в Visual С++ 2017 RC всегда полагается на среду выполнения concurrency, которая по умолчанию выполняет сгенерированный код конечного автомата в пуле потоков нить. Существует ли аналогичная концепция контекста синхронизации, которую пользовательское приложение может использовать для привязки выполнения coroutine к определенному потоку?
Кроме того, каков текущий по умолчанию "планировщик" поведения сопрограмм, реализованных в Visual С++ 2017 RC? т.е. 1) как точно указано условие ожидания? и 2) когда условие ожидания выполнено, кто вызывает "нижнюю половину" приостановленной сопрограммы?
Мое (наивное) предположение о планировании задач в С# заключается в том, что С# "реализует" условие ожидания чисто путем продолжения задачи - условие ожидания синтезируется задачей, принадлежащей TaskCompletionSource, и любая логика кода, которая должна ждать, будет скована как это продолжение, поэтому, если условие ожидания выполнено, например если полное сообщение получено от низкоуровневого сетевого обработчика, оно выполняет TaskCompletionSource.SetValue, которое переводит базовую задачу в завершенное состояние, эффективно позволяя логике продолжения цепочек запускаться (помещая задачу в состояние готовности/список из предыдущее созданное состояние). В С++ coroutine я предполагаю, что std:: future и std:: prom будут использоваться в качестве аналогичного механизма (std:: future - это задача, в то время как std:: prom - это объект TaskCompletionSource и использование тоже удивительно похоже!) - так ли планировщик С++ сопрограммы, если таковой имеется, полагается на какой-то аналогичный механизм для выполнения поведения?
[EDIT]: после некоторых дальнейших исследований я смог кодировать очень простую, но очень мощную абстракцию, которая называется awaitable, которая поддерживает однопоточную и совместную многозадачность, и имеет простой планировщик на основе thread_local, который может выполнять сопрограммы в потоке запускается корневая консоль. Код можно найти из этого github repo: https://github.com/llint/Awaitable
Ожидаемый композит таким образом, что он поддерживает правильное упорядочение вызовов на вложенных уровнях, и он имеет примитивный доход, время ожидания и готовность к настройке из другого места, и из этого может быть получен очень сложный шаблон использования (например, бесконечный цикл сопрограммы, которые только разбужаются, когда происходят определенные события), модель программирования следует за С# Task на основе async/await pattern. Пожалуйста, не стесняйтесь давать свои отзывы.