Boost.Coroutine2обеспечивает асимметричные координаты.
Реализации, которые производят последовательности значений, обычно используют асимметричные корутины.
Каждый экземпляр корутина имеет свой собственный стек.
В отличие от корутин без стека, стековые корутины позволяют вызывать операцию приостановки из произвольных подстеков, что позволяет проводить рекурсивные операции побега и повторного входа.
Корутина только подвижна.
Если бы он был копируемым, то его стек со всеми объектами, выделенными на нем, тоже был бы скопирован. Это привело бы к неопределенному поведению, если бы некоторые из этих объектов были классами RAII (управление ресурсом по шаблону RAII). Когда первая из рутинных копий завершится (раскручивает свой стек), деструкторы класса RAII выпустят свои управляемые ресурсы. Когда вторая копия заканчивается, те же деструкторы пытаются вдвойне высвободить те же ресурсы, что приводит к неопределенному поведению.
При корутинном разрушении ассоциированный стек будет развёрнут.
Конструктор корутина позволяет пройти кастомизированныйстек-распорядитель.стек-распорядительможет свободно распределять стек или кэшировать его для будущего использования (для корутин, созданных позже).
coroutine<>::push_typeиcoroutine<>::pull_typeподдерживают сегментированные стеки (рост по требованию).
Не всегда можно точно оценить необходимый размер стека - в большинстве случаев выделяется слишком много памяти (отходы виртуального адресного пространства).
При строительстве корутин начинается с минимального (по умолчанию) размера стека. Этот минимальный размер стека является максимальным размером страницы и каноническим размером для стека сигналов (макро-SIGSTKSZ на POSIX).
На момент написания только GCC (4.7)Известно, что они поддерживают сегментированные стеки. С версией 1.54Boost.Coroutine2обеспечивает поддержку сегментированных стеков.
Деструктор высвобождает связанный с ним стек. Реализатор может свободно распределять стек или кэшировать его для последующего использования.
Корутин сохраняет и восстанавливает регистры в соответствии с базовым ABI на каждом коммутаторе контекста (используяBoost.Context).
Некоторые приложения не используют регистры с плавающей запятой и могут отключить сохранение регистров FPU по причинам производительности.
![[Note]](/img/note.png) |
Note |
Согласно конвенции вызова, регистры FPU сохраняются по умолчанию. |
В системах POSIX коммутатор контекста не сохраняет маски сигналов по причинам производительности.
Переключатель контекста выполняется черезcoroutine<>::push_type::operator()иcoroutine<>::pull_type::operator().
![[Warning]](/img/warning.png) |
Warning |
coroutine<>::push_type::operator()иcoroutine<>::pull_type::operator()изнутритот жекорутин приводит к неопределенному поведению. |
Например, приведенный ниже код приведет к неопределенному поведению:
boost::coroutines2::coroutine<void>::push_type coro(
[&](boost::coroutines2::coroutine<void>::pull_type& yield){
coro();
});
coro();