C ++ 20 рдореЗрдВ, рдмреЙрдХреНрд╕ рдХреЗ рдмрд╛рд╣рд░ рдХреЛрд░рдЖрдЙрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рд╡рд╛рд▓рд╛ рд╣реИред рдпрд╣ рд╡рд┐рд╖рдп Yandex.Taxi рдкрд░ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдХрд░реАрдм рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИред (рдЕрдкрдиреА рдЬрд░реВрд░рддреЛрдВ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдврд╛рдВрдЪреЗ рдХрд╛ рд╡рд┐рдХрд╛рд╕ рдХрд░ рд░рд╣реЗ рд╣реИрдВ)ред рдЗрд╕рд▓рд┐рдП, рдЖрдЬ рд╣рдо Habr рдХреЗ рдкрд╛рдардХреЛрдВ рдХреЛ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджрд┐рдЦрд╛рдПрдВрдЧреЗ рдХрд┐ C ++ рд╕реНрдЯреИрдХрд▓реЗрд╕ рдХреЙрд░рдЖрдЙрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛рдПред
рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдЪрд▓реЛ рдХреБрдЫ рд╕рд░рд▓ рд▓реЗрддреЗ рд╣реИрдВ: рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдиреЗрдЯрд╡рд░реНрдХ рдЗрдВрдЯрд░рдлреЗрд╕, рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЯрд╛рдЗрдорд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд┐рдП рдмрд┐рдирд╛, рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдорд┐рд▓рдХрд░ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдХреЙрд▓рдмреИрдХ рд╕реЗ рдЗрд╕ "рдиреВрдбрд▓" рдХреЛ рдорд╣рд╕реВрд╕ рдХрд░рдиреЗ рдФрд░ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ:

void FuncToDealWith() { InCurrentThread(); writerQueue.PushTask([=]() { InWriterThread1(); const auto finally = [=]() { InWriterThread2(); ShutdownAll(); }; if (NeedNetwork()) { networkQueue.PushTask([=](){ auto v = InNetworkThread(); if (v) { UIQueue.PushTask([=](){ InUIThread(); writerQueue.PushTask(finally); }); } else { writerQueue.PushTask(finally); } }); } else { finally(); } }); }
рдкрд░рд┐рдЪрдп
Coroutines рдпрд╛ coroutines рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкреВрд░реНрд╡ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╕реНрдерд╛рди рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХрдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИ; рд╕реНрдерд╛рдиреАрдп рдЪрд░ рдХреЗ рд╕рд╛рде рд░реЛрдХрд╛ рд╕рдорд╛рд░реЛрд╣ рдХреЗ рдкреВрд░реЗ рд░рд╛рдЬреНрдп рдореЗрдВ рдХрд╣реАрдВ рдкрд╛рд╕; рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЙрд╕реА рд╕реНрдерд╛рди рд╕реЗ рдЪрд▓рд╛рдПрдВ рдЬрд╣рд╛рдВ рд╣рдордиреЗ рдЗрд╕реЗ рд░реЛрдХрд╛ рдерд╛ред
рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рдХрдИ рд╕реНрд╡рд╛рдж рд╣реИрдВ: рд╕реНрдЯреИрдХрд▓реЗрд╕ рдФрд░ рд╕реНрдЯреИрдХрдлреБрд▓ред рд╣рдо рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдж рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗред
рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдмрдпрд╛рди
рд╣рдорд╛рд░реА рдХрдИ рдХрд╛рд░реНрдп рдХрддрд╛рд░реЗрдВ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдп рдореЗрдВ рдХреБрдЫ рдХрд╛рд░реНрдп рд╣реЛрддреЗ рд╣реИрдВ: рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдЦреАрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрддрд╛рд░ рд╣реЛрддреА рд╣реИ, рдиреЗрдЯрд╡рд░реНрдХ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рдХрддрд╛рд░ рд╣реЛрддреА рд╣реИ, рдФрд░ рдПрдХ рдбрд┐рд╕реНрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрддрд╛рд░ рд╣реЛрддреА рд╣реИред рд╕рднреА рдХрддрд╛рд░реЗрдВ рд╡рд░реНрдХрдХреНрд╡реЗрдп рд╡рд░реНрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВ рдЬрд┐рдирдореЗрдВ рд╢реВрдиреНрдп рдкреБрд╖реНрдкрдХ рд╡рд┐рдзрд┐ (std :: function <void ()> рдХрд╛рд░реНрдп) рд╣реИред рдХрддрд╛рд░реЗрдВ рдЙрди рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рд╕рдордп рддрдХ рдЬреАрд╡рд┐рдд рд░рд╣рддреА рд╣реИрдВ (рдЬрдм рд╣рдо рдЗрд╕рдореЗрдВ рдХреЛрдИ рдмрдХрд╛рдпрд╛ рдХрд╛рд░реНрдп рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдРрд╕реА рд╕реНрдерд┐рддрд┐ рдХреЛ рдирд╖реНрдЯ рдХрд░ рджреЗрддреЗ рд╣реИрдВ)ред
FuncToDealWith () рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдХрд╛рд░реНрдп рд╡рд┐рднрд┐рдиреНрди рдХрддрд╛рд░реЛрдВ рдореЗрдВ рдХреБрдЫ рддрд░реНрдХ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░, рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдПрдХ рдирдпрд╛ рдХрд╛рд░реНрдп рдХрддрд╛рд░ рдореЗрдВ рд░рдЦрддрд╛ рд╣реИред
рд╣рдо рдПрдХ рд░реИрдЦрд┐рдХ рдЫрджреНрдо рдХреЛрдб рдХреЗ рд░реВрдк рдореЗрдВ рдХреЙрд▓рдмреИрдХ рдХреЗ "рдиреВрдбрд▓реНрд╕" рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдпрд╣ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддреЗ рд╣реБрдП рдХрд┐ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
void CoroToDealWith() { InCurrentThread();
рд▓рдЧрднрдЧ рдЗрд╕ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдореИрдВ рд╣рд╛рд╕рд┐рд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред
рд╕реАрдорд╛рдПрдБ рд╣реИрдВ:
- рдХрддрд╛рд░ рдХреЗ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЛ рдирд╣реАрдВ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдЕрдиреНрдп рднрд╛рдЧреЛрдВ рдореЗрдВ рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЖрдк рдбреЗрд╡рд▓рдкрд░ рдХреЛрдб рдирд╣реАрдВ рддреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдирдИ рдХрддрд╛рд░ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдирд╣реАрдВ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред
- рдЖрдк FuncToDealWith рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдирд╣реАрдВ рдмрджрд▓ рд╕рдХрддреЗред рдЖрдк рдХреЗрд╡рд▓ рдЗрд╕рдХрд╛ рдирд╛рдо рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрдк рдЗрд╕реЗ рдХрд┐рд╕реА рднреА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдШрд░ рдкрд░ рд░рдЦрдирд╛ рд╣реЛрдЧрд╛ред
- рдкрд░рд┐рдгрд╛рдореА рдХреЛрдб рдореВрд▓ (рдпрд╛ рдЗрд╕рд╕реЗ рднреА рдЕрдзрд┐рдХ рдЙрддреНрдкрд╛рджрдХ) рдХреЗ рд░реВрдк рдореЗрдВ рдЙрддреНрдкрд╛рджрдХ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдирд┐рд░реНрдгрдп
рдкреБрдирд░реНрд╡рд┐рддрд░рдг FuncToDealWith рдлрд╝рдВрдХреНрд╢рди
Coroutines TS рдореЗрдВ, coroutine рдЯреНрдпреВрдирд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд░рд┐рдЯрд░реНрди рдорд╛рди рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕реЗрдЯ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдкреНрд░рдХрд╛рд░ рдХреБрдЫ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдлрд╝рдВрдХреНрд╢рди рдмреЙрдбреА рдХреЗ рдЕрдВрджрд░ рдЖрдк рдирдП рдХреАрд╡рд░реНрдб co_await / co_return / co_ield рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдХрддрд╛рд░реЛрдВ рдХреЗ рдмреАрдЪ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо co_yield рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ:
CoroTask CoroToDealWith() { InCurrentThread(); co_yield writerQueue; InWriterThread1(); if (NeedNetwork()) { co_yield networkQueue; auto v = InNetworkThread(); if (v) { co_yield UIQueue; InUIThread(); } } co_yield writerQueue; InWriterThread2(); ShutdownAll(); }
рдпрд╣ рдЕрдВрддрд┐рдо рдЦрдВрдб рд╕реЗ рдЫрджреНрдордХреЛрд╢ рдХреЗ рд╕рдорд╛рди рдирд┐рдХрд▓рд╛ред рдХреЙрд░рдЯрд╛рдЗрдиреНрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА "рдЬрд╛рджреВ" рдХреЛ рдХреЛрд░рдЯрд╕реНрдХ рдХреНрд▓рд╛рд╕ рдореЗрдВ рдЫрд┐рдкрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
CoroTask
рд╕рдмрд╕реЗ рд╕рд░рд▓ (рд╣рдорд╛рд░реЗ) рдорд╛рдорд▓реЗ рдореЗрдВ, рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ "рдЯреНрдпреВрдирд░" рд╡рд░реНрдЧ рдХреА рд╕рд╛рдордЧреНрд░реА рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рд╣реА рдЙрд░реНрдл тАЛтАЛрд╢рд╛рдорд┐рд▓ рд╣реИ:
#include <experimental/coroutine> struct CoroTask { using promise_type = PromiseType; };
рд╡рд╛рджрд╛_рдЯрд╛рдЗрдк рдПрдХ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдореЗрдВ рдЦреБрдж рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рдореЗрдВ рддрд░реНрдХ рд╣реИ рдЬреЛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ:
- рдХреЛрд░рдЯрд╛рдЗрди рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдкрд░ рдХреНрдпрд╛ рдХрд░реЗрдВ
- рдЬрдм рдЖрдк рдкрд╣рд▓реА рдмрд╛рд░ corutin рджрд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдХреНрдпрд╛ рдХрд░реЗрдВ
- рдЬреЛ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдореБрдХреНрдд рдХрд░рддрд╛ рд╣реИ
- рдХреЛрд░рдЯрд╛рдЗрди рд╕реЗ рдмрд╛рд╣рд░ рдЙрдбрд╝рд╛рди рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ
- рдХреИрд╕реЗ рдПрдХ CoroTask рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП
- рдЕрдЧрд░ рдХреЙрд░рдЯрд┐рди рдХреЗ рдЕрдВрджрд░ co_yield рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдХреНрдпрд╛ рдХрд░реЗрдВ
рдЙрдкрдирд╛рдо рд╡рд╛рджрд╛_ рдкреНрд░рдХрд╛рд░ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рдЖрдк рдЙрдкрдирд╛рдо рдирд╛рдо рдХреЛ рдХрд┐рд╕реА рдФрд░ рдЪреАрдЬрд╝ рдореЗрдВ рдмрджрд▓рддреЗ рд╣реИрдВ, рддреЛ рдХрдВрдкрд╛рдЗрд▓рд░ рд╢рдкрде рд▓реЗрдЧрд╛ рдФрд░ рдХрд╣реЗрдЧрд╛ рдХрд┐ рдЖрдкрдиреЗ рдХреЛрд░реЛрд╕реНрдХ рдХреЛ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рд▓рд┐рдЦрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, CoroTask рдирд╛рдо рдХреЛ рдЖрдк рдкрд╕рдВрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд▓реЗрдХрд┐рди рдЕрдЧрд░ рд╡рд╛рджреЗ_рдЯрд╛рдЗрдк рдореЗрдВ рд╕рдм рдХреБрдЫ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рддреЛ рдпрд╣ рдХреЛрд░реЛрд╕реНрдХ рдХреНрдпреЛрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИ?рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЖрдк рдХреЛрд░реЛрд╕реНрдХ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЖрдкрдХреЛ рдПрдХ рд░реБрдХреЗ рд╣реБрдП рдХреЛрд░рдЖрдЙрдЯ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд░ рдХрд░рдиреЗ, рдЙрд╕рд╕реЗ рдбреЗрдЯрд╛ рднреЗрдЬрдиреЗ рдФрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ, рдЬрд╛рдЧрдиреЗ рдФрд░ рдЙрд╕реЗ рдирд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред
PromiseType
рдордЬрд╝рд╛ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП рд╣реЛ рд░рд╣реА рд╣реИред рд╣рдо corutin рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ:
class WorkQueue;
рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдореЗрдВ, рдЖрдк рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ std :: рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ :: suspend_never рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ рдЬреЛ рдХрд╣рддрд╛ рд╣реИ рдХрд┐ рдХреЛрд░рдЯрд┐рди рдХреЛ рд░реЛрдХрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд рднреА рд╣реИ - рдкреНрд░рдХрд╛рд░ std :: рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ :: suspend_always, рдЬреЛ рдЖрдкрдХреЛ рдХреЛрд░рдЯрд┐рди рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддрд╛ рд╣реИред рдпреЗ рдкреНрд░рдХрд╛рд░ рддрдерд╛рдХрдерд┐рдд рдкреНрд░рддреАрдХреНрд╖рд╛рдпреЛрдЧреНрдп рд╣реИрдВред рдпрджрд┐ рдЖрдк рдЙрдирдХреА рдЖрдВрддрд░рд┐рдХ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдЪрд┐рдВрддрд╛ рди рдХрд░реЗрдВ, рд╣рдо рдЬрд▓реНрдж рд╣реА рд╣рдорд╛рд░реЗ рдЖрд╡рд╛рдЗрдЯреНрд╕ рд▓рд┐рдЦреЗрдВрдЧреЗред
рдКрдкрд░ рджрд┐рдП рдЧрдП рдХреЛрдб рдореЗрдВ рд╕рдмрд╕реЗ рдЧреИрд░-рддреБрдЪреНрдЫ рд╕реНрдерд╛рди рдЕрдВрддрд┐рдо_рд╕рдкреЗрдВрдб () рд╣реИред рд╕рдорд╛рд░реЛрд╣ рдореЗрдВ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рдкреНрд░рднрд╛рд╡ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рд╣рдо рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рд░реЛрдХрддреЗ рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рд╕рдВрдХрд▓рдХ рджреНрд╡рд╛рд░рд╛ рдХреЛрд░рдЯрд╛рдЗрди рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдП рдЧрдП рд╕рдВрд╕рд╛рдзрди рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рдВрдХрд▓рдХ рдХреЛ рд╕рд╛рдл рдХрд░реЗрдВрдЧреЗред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╣рдо рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рд░реЛрдХрддреЗ рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, std :: рдкреНрд░рд╛рдпреЛрдЧрд┐рдХ :: suspend_always {}) рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдХрд╣реАрдВ рдмрд╛рд╣рд░ рд╕реЗ рдЦрд╛рд▓реА рдХрд░рдирд╛ рд╣реЛрдЧрд╛: рдЖрдкрдХреЛ рдПрдХ рд╕реНрдорд╛рд░реНрдЯ рдкреЙрдЗрдВрдЯрд░ рдХреЛ рдХреЛрд░рдЯрд╛рдЗрди рдХреЛ рдХрд╣реАрдВ рдФрд░ рд╕рд╣реЗрдЬрдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдирд╖реНрдЯ рдХрд░рдирд╛ ()ред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдпрд╣ рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред
рдкреНрд░реЛрддреНрд╕рд╛рд╣рди рд╡рд╛рджрд╛ :: рдЙрдкрдЬ_рд╡рд╛рдпреБ
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ PromiseType :: рдпреАрд▓реНрдб_рд╡реЗрд▓реНрдпреВ рд▓рд┐рдЦрдирд╛ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдкрдВрдХреНрддрд┐ рд╣реИ; рдХреЛрд░рдЯрд╛рдЗрди, рдЬрд┐рд╕реЗ рдирд┐рд▓рдВрдмрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЗрд╕ рдмрд╛рд░реА рдореЗрдВ:
auto PromiseType::yield_value(WorkQueue& wq) {
рдФрд░ рдпрд╣рд╛рдБ рд╣рдо рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╣реБрдд рдмрдбрд╝реЗ рдФрд░ рдореБрд╢реНрдХрд┐рд▓ рд╕реЗ рд╕рд╛рдордирд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рд╣рдордиреЗ рдкрд╣рд▓реЗ рдХреЛрд░рдЯрд╛рдЗрди рдХреЛ рдХрддрд╛рд░ рдореЗрдВ рд░рдЦрд╛ рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА рдЗрд╕реЗ рдирд┐рд▓рдВрдмрд┐рдд рдХрд░ рджрд┐рдпрд╛ред рдРрд╕рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдХреЛрд░рдЖрдЙрдЯ рдХреЛ рдХрддрд╛рд░ рд╕реЗ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рдП рдФрд░ рд╡рд░реНрддрдорд╛рди рдереНрд░реЗрдб рдореЗрдВ рдирд┐рд▓рдВрдмрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣реА рдЗрд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рд╢реБрд░реВ рд╣реЛ рдЬрд╛рдПред рдпрд╣ рдПрдХ рджреМрдбрд╝ рдХреА рд╕реНрдерд┐рддрд┐, рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдФрд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкрд╛рдЧрд▓ рд░рдирдЯрд╛рдЗрдо рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЬрдиреНрдо рджреЗрдЧрд╛ред
рд╕рд╣реА рд╡рд╛рджрд╛ :: рдЙрдкрдЬ_рд╡рд╛рдпреБ
рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рдкрд╣рд▓реЗ рдХреЙрд░рдЯрд┐рди рдХреЛ рд░реЛрдХрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА рдЗрд╕реЗ рдХрддрд╛рд░ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрдкрдиреА Awaitable рд▓рд┐рдЦреЗрдВрдЧреЗ рдФрд░ рдЗрд╕реЗ schedule_for_execution рдХрд╣реЗрдВрдЧреЗ:
auto PromiseType::yield_value(WorkQueue& wq) { struct schedule_for_execution { WorkQueue& wq; constexpr bool await_ready() const noexcept { return false; } void await_suspend(std::experimental::coroutine_handle<> this_coro) const { wq.PushTask(this_coro); } constexpr void await_resume() const noexcept {} }; return schedule_for_execution{wq}; }
рдХрдХреНрд╖рд╛рдПрдВ std :: рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ :: suspend_always, std :: рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ :: suspend_never, Schedule_for_execution рдФрд░ рдЕрдиреНрдп Awaitables рдореЗрдВ 3 рдХрд╛рд░реНрдп рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдХреЛрд░рдЯрд╛рдЗрди рдХреЛ рд░реЛрдХрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдкреНрд░рддреАрдХреНрд╖рд╛ рд╣реЛ рд░рд╣реА рд╣реИред рдХрд╛рд░реНрдпрдХреНрд░рдо рдмрдВрдж рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдкреБрдХрд╛рд░рд╛ рдЬрд╛рддрд╛ рд╣реИ, рд░реБрдХреЗ рд╣реБрдП рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рд╣реИрдВрдбрд▓ рдХреЛ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬрдм coroutine рдирд┐рд╖реНрдкрд╛рджрди рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ wait_resume рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред
рдФрд░ рддреНрд░рд┐рдХреЛрдгреАрдп рд╕реНрдХреИрдмреНрд╕ std :: рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ :: coroutine_handle <> рдореЗрдВ рдХреНрдпрд╛ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ?рдЖрдк рд╡рд╣рд╛рдВ PromiseType рдкреНрд░рдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЙрджрд╛рд╣рд░рдг рдмрд┐рд▓реНрдХреБрд▓ рдЙрд╕реА рддрд░рд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛ :)
std :: рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ :: coroutine_handle <> (aka std :: рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ :: coroutine_handle <void>) рд╕рднреА std :: рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ :: coroutine_handle <DataType> рдХреЗ рд▓рд┐рдП рдЖрдзрд╛рд░ рдкреНрд░рдХрд╛рд░ рд╣реИ, рдЬрд╣рд╛рдБ DataType рд╡рд░реНрддрдорд╛рди coroutine рдХрд╛ рд╡рд╛рджрд╛_рдкреНрд░рдХрд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рдЖрдкрдХреЛ DataType рдХреА рдЖрдВрддрд░рд┐рдХ рд╕рд╛рдордЧреНрд░реА рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдк std :: рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ :: coroutine_handle <> рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдЙрди рдЬрдЧрд╣реЛрдВ рдкрд░ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬрд╣рд╛рдБ рдЖрдк рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд╛рджреЗ_рдкреНрд░рдХрд╛рд░ рд╕реЗ рдЕрдореВрд░реНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЙрдкрдпреЛрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рд╣реЛ рдЧрдпрд╛
рдЖрдк
рд╕рдВрдХрд▓рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
, рдЙрджрд╛рд╣рд░рдг рдХреЛ рдСрдирд▓рд╛рдЗрди рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╣рд░ рддрд░рд╣ рд╕реЗ рдкреНрд░рдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдФрд░ рдЕрдЧрд░ рдореБрдЭреЗ co_yield рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИ, рддреЛ рдХреНрдпрд╛ рдореИрдВ рдЗрд╕реЗ рдХрд┐рд╕реА рдЪреАрдЬрд╝ рд╕реЗ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реВрдВ?Co_await рд╕реЗ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, PromiseType рдореЗрдВ рдирд┐рдореНрди рдлрд╝рдВрдХреНрд╢рди рдЬреЛрдбрд╝реЗрдВ:
auto await_transform(WorkQueue& wq) { return yield_value(wq); }
рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдореИрдВ co_await рдХреА рддрд░рд╣ рдирд╣реАрдВ рд╣реВрдБ?рдмрд╛рдд рдмреБрд░реА рд╣реИред рдХреБрдЫ рдирд╣реАрдВ рдмрджрд▓рдирд╛ рд╣реИред
рдзреЛрдЦрд╛ рдХреА рдЪрд╛рджрд░
рдХреЛрд░реЛрдЯрд╕реНрдХ рдПрдХ рдРрд╕рд╛ рд╡рд░реНрдЧ рд╣реИ рдЬреЛ рдПрдХ рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдпрд╣ рдЖрдкрдХреЛ рдПрдХ рд░реБрдХреЗ рд╣реБрдП рдХреЛрд░рдЖрдЙрдЯ рдХреЗ рд╕рд╛рде рд╕рдВрд╡рд╛рдж рдХрд░рдиреЗ рдФрд░ рдЗрд╕рд╕реЗ рдХреЛрдИ рдбреЗрдЯрд╛ рд▓реЗрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
CoroTask :: рд╡рд╛рджрд╛_рдЯрд╛рдЗрдк рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рдФрд░ рдХрдм рдХреЛрд░рдЯрд╛рдЗрди рд░реБрдХрддреЗ рд╣реИрдВ, рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдХреИрд╕реЗ рдореБрдХреНрдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдХреИрд╕реЗ CoroTask рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╣реИрдВред
рдкреНрд░рддреАрдХреНрд╖рд╛рд░рдд (std :: рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ :: suspend_always, std :: рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ :: suspend_never, Schedule_for_execution рдФрд░ рдЕрдиреНрдп) рд╕рдВрдХрд▓рдХ рдХреЛ рдмрддрд╛рдПрдВ рдХрд┐ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдмрд┐рдВрджреБ рдкрд░ рдХреЙрд░рдЯреАрди рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ (рдХреНрдпрд╛ рдХреЛрд░рдЯрд┐рди рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рд░реБрдХреЗ рд╣реБрдП рдХреЙрд░рдЯрд┐рди рдХрд╛ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ рдФрд░ рдХреЛрд░рдЯреАрди рдЬрд╛рдЧрдиреЗ рдкрд░ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ) ред
рдЕрдиреБрдХреВрд▓рди
рд╣рдорд╛рд░реЗ PromiseType рдореЗрдВ рдПрдХ рджреЛрд╖ рд╣реИред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЕрдЧрд░ рд╣рдо рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╕рд╣реА рдХрд╛рд░реНрдп рдХрддрд╛рд░ рдореЗрдВ рдЪрд▓ рд░рд╣реЗ рд╣реИрдВ, рддрдм рднреА рдХреЙрд▓рд┐рдВрдЧ_рдСрдпрд▓реНрдб рдХреЙрд░рдЯрд╛рдЙрдЗрди рдХреЛ рдирд┐рд▓рдВрдмрд┐рдд рдХрд░реЗрдЧрд╛ рдФрд░ рдЗрд╕реЗ рдЙрд╕реА рдХрд╛рд░реНрдп рдХрддрд╛рд░ рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд░рдЦреЗрдЧрд╛ред рдпрд╣ рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдмрд▓реНрдХрд┐ рддреБрд░рдВрдд рдирд┐рд╖реНрдкрд╛рджрди рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЗрд╖реНрдЯрддрдо рд╣реЛрдЧрд╛ред
рдЖрдЗрдП рд╣рдо рдЗрд╕ рджреЛрд╖ рдХреЛ рдареАрдХ рдХрд░реЗрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, PromiseType рдореЗрдВ рдПрдХ рдирд┐рдЬреА рдлрд╝реАрд▓реНрдб рдЬреЛрдбрд╝реЗрдВ:
WorkQueue* current_queue_ = nullptr;
рдЗрд╕рдореЗрдВ, рд╣рдо рдЙрд╕ рдХреНрдпреВ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдкрдХрдбрд╝реЗрдВрдЧреЗ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВред
рдЕрдЧрд▓рд╛, рд╡рд╛рджрд╛ рдХрд░реЗрдВ
auto PromiseType::yield_value(WorkQueue& wq) { struct schedule_for_execution { const bool do_resume; WorkQueue& wq; constexpr bool await_ready() const noexcept { return do_resume; } void await_suspend(std::experimental::coroutine_handle<> this_coro) const { wq.PushTask(this_coro); } constexpr void await_resume() const noexcept {} }; const bool do_not_suspend = (current_queue_ == &wq); current_queue_ = &wq; return schedule_for_execution{do_not_suspend, wq}; }
рдпрд╣рд╛рдБ рд╣рдордиреЗ рд╢рд┐рдбреНрдпреВрд▓_рдлреЛрд░реНрд╕_рдПрдХреНрдЬрд╝реАрдХреЗрд╢рди :: wait_ready () рдХреЛ рдЯреНрд╡реАрдХ рдХрд┐рдпрд╛ред рдЕрдм рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдпрджрд┐ рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдп рдЬрд┐рд╕ рдкрд░ рд╣рдо рд╢реБрд░реВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЙрд╕рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реЛ рддреЛ рдХреЛрд░рдЯрд╛рдЗрди рдХреЛ рдирд┐рд▓рдВрдмрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рд╣реЛ рдЧрдпрд╛ред рдЖрдк
рд╣рд░ рддрд░рд╣ рд╕реЗ рдкреНрд░рдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
рдореВрд▓ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, WorkQueue :: PushTask (std :: function <void ()> f) рдХреЗ рд╣рд░ рдХреЙрд▓ рдХреЗ рд╕рд╛рде, рд╣рдордиреЗ рд▓реИрдореНрдмреНрдбрд╛ рд╕реЗ рдХреНрд▓рд╛рд╕ std :: function <void ()> рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдпрд╛ред рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЛрдб рдореЗрдВ, рдпреЗ рд▓рдВрдмреЛрджрд╛ рдЕрдХреНрд╕рд░ рдЖрдХрд╛рд░ рдореЗрдВ рдХрд╛рдлреА рдмрдбрд╝реЗ рд╣реЛрддреЗ рд╣реИрдВ, рдпрд╣реА рд╡рдЬрд╣ рд╣реИ рдХрд┐ std :: function <void ()> рдХреЛ рдореЗрдордиреЗ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдореГрддрд┐ рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
Coroutine рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо std :: function <void ()> std :: рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ :: coroutine_handle <> рдХреЗ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддреЗ рд╣реИрдВред Std рдХрд╛ рдЖрдХрд╛рд░ :: рдкреНрд░рд╛рдпреЛрдЧрд┐рдХ :: coroutine_handle <> рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХрд╛рдВрд╢ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЗрд╕рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рдиреНрдпреВрдирддрдо рд░рдЦрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рддреЛ рдХреНрд▓реИрдВрдЧ рдкрд░ рдЗрд╕рдХрд╛ рдЖрдХрд╛рд░ рдЖрдХрд╛рд░ (рд╢реВрдиреНрдп *) рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред рдЬрдм std :: function <void ()> рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЫреЛрдЯреА рд╡рд╕реНрддреБрдУрдВ рд╕реЗ рдбрд╛рдпрдиреЗрдорд┐рдХ рдПрд▓реЛрдХреЗрд╢рди рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред
рдХреБрд▓ - Coroutines рдХреЗ рд╕рд╛рде рд╣рдореЗрдВ рдХрдИ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдЧрддрд┐рд╢реАрд▓ рдЖрд╡рдВрдЯрди рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдорд┐рд▓рд╛ред
рд▓реЗрдХрд┐рди! рдХрдВрдкрд╛рдЗрд▓рд░ рдЕрдХреНрд╕рд░ рд╕реНрдЯреИрдХ рдкрд░ рд╕рднреА рдХреЛрд░рдЯрд╛рдЗрди рдХреЛ рдирд╣реАрдВ рдмрдЪрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдХрд╛рд░рдг, CoroToDealWith рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рддреЗ рд╕рдордп рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдЧрддрд┐рд╢реАрд▓ рдЖрд╡рдВрдЯрди рд╕рдВрднрд╡ рд╣реИред
рд╕реНрдЯреИрдХрд▓реЗрд╕ рдмрдирд╛рдо рд╕реНрдЯреИрдХрдлреБрд▓
рд╣рдордиреЗ рд╕рд┐рд░реНрдл рд╕реНрдЯреИрдХрд▓реЗрд╕ рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд┐рдпрд╛, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдВрдкрд╛рдЗрд▓рд░ рдХрд╛ рд╕рдорд░реНрдерди рдЪрд╛рд╣рд┐рдПред рд╕реНрдЯреИрдХрдлреБрд▓ рдХреЙрд░рдЖрдЙрдЯ рднреА рд╣реИрдВ рдЬреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕реНрддрд░ рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдкрд╣рд▓реЗ рд╡рд╛рд▓реЗ рд╕реНрдореГрддрд┐ рдХреЗ рдЕрдзрд┐рдХ рдХрд┐рдлрд╛рдпрддреА рдЖрд╡рдВрдЯрди рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ, рд╕рдВрднрд╡рддрдГ рд╡реЗ рд╕рдВрдХрд▓рдХ рджреНрд╡рд╛рд░рд╛ рдмреЗрд╣рддрд░ рдЕрдиреБрдХреВрд▓рд┐рдд рд╣реЛрддреЗ рд╣реИрдВред рдореМрдЬреВрджрд╛ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рджреВрд╕рд░реЗ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЙрдиреНрд╣реЗрдВ рдХрдо рдХреЛрдб рд╕рдВрд╢реЛрдзрдиреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдЖрдк рдЕрдВрддрд░ рдорд╣рд╕реВрд╕ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рдФрд░ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдкрд░рд┐рдгрд╛рдо
рд╣рдордиреЗ рдореВрд▓ рдЙрджрд╛рд╣рд░рдг рдХреА рдЬрд╛рдВрдЪ рдХреА рдФрд░ рдПрдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд╡рд░реНрдЧ рдХреЛрд░реЛрдЯрд╕реНрдХ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдиреНрдп рдХреЛрд░рдЯрд╛рдЗрдиреНрд╕ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рд╕рд╛рде рдХреЛрдб рднреЛрд▓реЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде рдЕрдзрд┐рдХ рдкрдардиреАрдп рдФрд░ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЙрддреНрдкрд╛рджрдХ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ:
рдпрд╣ рдерд╛ | рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рд╕рд╛рде |
---|
void FuncToDealWith() { InCurrentThread(); writerQueue.PushTask([=]() { InWriterThread1(); const auto fin = [=]() { InWriterThread2(); ShutdownAll(); }; if (NeedNetwork()) { networkQueue.PushTask([=](){ auto v = InNetThread(); if (v) { UIQueue.PushTask([=](){ InUIThread(); writerQueue.PushTask(fin); }); } else { writerQueue.PushTask(fin); } }); } else { fin(); } }); } | CoroTask CoroToDealWith() { InCurrentThread(); co_yield writerQueue; InWriterThread1(); if (NeedNetwork()) { co_yield networkQueue; auto v = InNetThread(); if (v) { co_yield UIQueue; InUIThread(); } } co_yield writerQueue; InWriterThread2(); ShutdownAll(); } |
рдУрд╡рд░рдмреЛрд░реНрдб рдереЗ рдХреБрдЫ рдкрд▓:
- рдХреЛрд░реБрдЯрд┐рди рд╕реЗ рдПрдХ рдФрд░ рдХреЙрд░рдЖрдЙрдЯ рдХреЛ рдХреИрд╕реЗ рдХреЙрд▓ рдХрд░реЗрдВ рдФрд░ рдЗрд╕рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВ
- рдХреНрдпрд╛ рдЙрдкрдпреЛрдЧреА рд╕рд╛рдорд╛рди рдЖрдк CoroTask рдореЗрдВ рд░рдЯрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
- рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЬреЛ рд╕реНрдЯреИрдХрд▓реЗрд╕ рдФрд░ рд╕реНрдЯреИрдХрдлреБрд▓ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХрд░рддрд╛ рд╣реИ
рдЕрдиреНрдп
рдпрджрд┐ рдЖрдк C ++ рднрд╛рд╖рд╛ рдХреЗ рдЕрдиреНрдп рд╕рд╕реНрддрд╛ рдорд╛рд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реАрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдпрд╛ рдЕрдкрдиреЗ рд╕рд╣рдпреЛрдЧрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде pluses рдкрд░ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рд╕рдВрд╡рд╛рдж рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ C ++ рднрд╛рд╖рд╛ рд╕рдореНрдореЗрд▓рди рджреЗрдЦреЗрдВред рдЕрдЧрд▓реЗ рдПрдХ
6 рдЕрдХреНрдЯреВрдмрд░ рдХреЛ рдирд┐рдЬрд╝рдиреА рдиреЛрд╡рдЧреЛрд░реЛрдб рдореЗрдВ рдЖрдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ C ++ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рджрд░реНрдж рд╣реИ рдФрд░ рднрд╛рд╖рд╛ рдореЗрдВ рдХреБрдЫ рд╕реБрдзрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдпрд╛ рдмрд╕ рд╕рдВрднрд╡ рдирд╡рд╛рдЪрд╛рд░реЛрдВ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ
https://stdcpp.ru/ рдореЗрдВ рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред
рдареАрдХ рд╣реИ, рдЕрдЧрд░ рдпрд╣ рдЖрдкрдХреЛ рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ Yandex.Taxi рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХрд╛рд░реНрдп рд╣реИрдВ рдЬреЛ рдЧреНрд░рд╛рдлрд╝ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рдПрдХ рд╕реБрдЦрдж рдЖрд╢реНрдЪрд░реНрдп рд╣реЛ рдЧрдпрд╛ :)
11 рдЕрдХреНрдЯреВрдмрд░ рдХреЛ рд╣рдореЗрдВ рдпрд╛рддреНрд░рд╛ рдХрд░реЗрдВ , рд╣рдо C ++ рдФрд░ рдЕрдзрд┐рдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗред