
рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ ... рдЬрдм рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдЗрд╕ рд╢рдмреНрдж рдХреЛ рд╕реБрдирддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЗ рд▓рд┐рдП рдЖрдБрдЦреЗрдВ рдЪрдордХрдиреЗ рд▓рдЧрддреА рд╣реИрдВ, рд╕рд╛рдБрд╕ рдЙрдерд▓реА рд╣реЛ рдЬрд╛рддреА рд╣реИ, рд╣рд╛рде рд╣рд┐рд▓рдиреЗ рд▓рдЧрддреЗ рд╣реИрдВ, рдЖрд╡рд╛рдЬ рдЕрдЯрдХрдиреЗ рд▓рдЧрддреА рд╣реИ, рдорд╕реНрддрд┐рд╖реНрдХ рдХрдИ рд╕реНрддрд░реЛрдВ рдкрд░ рдЕрдорд▓ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрддрд╛ рд╣реИ ... рдкреНрд░рдмрдВрдзрдХреЛрдВ рдХреА рдЖрдБрдЦреЗрдВ рдЪреМрдбрд╝реА рд╣реЛ рдЬрд╛рддреА рд╣реИрдВ, рдЖрд╡рд╛рдЬрд╝реЗрдВ рд╣рд▓реНрдХреА рд╣реЛ рдЬрд╛рддреА рд╣реИрдВ, рд╣рд╛рде рдореБрдЯреНрдареА рдореЗрдВ рджрдм рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдЖрд╡рд╛рдЬрд╝ рдкрд▓рдЯ рдЬрд╛рддреА рд╣реИред ... рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдЬреЛ рдЙрдиреНрд╣реЗрдВ рдПрдХрдЬреБрдЯ рдХрд░рддреА рд╣реИ рд╡рд╣ рдПрдХ рддреЗрдЬреА рд╕реЗ рдирд╛рдбрд╝реА рд╣реИред рдХреЗрд╡рд▓ рдЗрд╕рдХреЗ рдХрд╛рд░рдг рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╣реИрдВ: рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд▓рдбрд╝рд╛рдИ рдХреЗ рд▓рд┐рдП рдЙрддреНрд╕реБрдХ рд╣реИрдВ, рдФрд░ рдкреНрд░рдмрдВрдзрдХ рдХреНрд░рд┐рд╕реНрдЯрд▓ рдмреЙрд▓ рдХреЛ рджреЗрдЦрдиреЗ рдФрд░ рдЬреЛрдЦрд┐рдореЛрдВ рдХрд╛ рдПрд╣рд╕рд╛рд╕ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд╡реЗ рд╕рдордп рдХреЗ рд╕рд╛рде рд╕рдордп рдмрдврд╝рдиреЗ рдХреЗ рдХрд╛рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдШрд░реНрд╖рдг рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрддреЗ рд╣реИрдВ ... рдФрд░ рдХреЗрд╡рд▓ рддрдм, рдЬрдм рдЕрдзрд┐рдХрд╛рдВрд╢ рдХреЛрдб рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╕рднреА рдХреЛ рдорд╣рд╕реВрд╕ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдФрд░ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЦрд░реНрдЪ рдХреА рдХрдбрд╝рд╡рд╛рд╣рдЯ рдХрд╛ рдПрд╣рд╕рд╛рд╕ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдПрдХ рдбрд┐рдмрдЧрд░ рдореЗрдВ рдЕрдВрддрд╣реАрди рд░рд╛рддреЗрдВ, рдЬреЛ рд╕рдордЭрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реА рдереА ...
рдпрд╣ рдПрдХ рдРрд╕реА рддрд╕реНрд╡реАрд░ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдореЗрд░реА рд╡реНрдпрдерд╛ рдХрд▓реНрдкрдирд╛ "рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ" рд╢рдмреНрдж рдХреЗ рд╕рд╛рде рд╣реИред рдмреЗрд╢рдХ, рдпрд╣ рд╕рдм рдмрд╣реБрдд рднрд╛рд╡рдирд╛рддреНрдордХ рд╣реИ рдФрд░ рд╣рдореЗрд╢рд╛ рд╕рдЪ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдЖрдЦрд┐рд░рдХрд╛рд░, рд╕рд╣реА? .. рд╡рд┐рдХрд▓реНрдк рд╕рдВрднрд╡ рд╣реИред рдХреБрдЫ рдХрд╣реЗрдВрдЧреЗ рдХрд┐ "рд╕рд╣реА рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде, рд╕рдмрдХреБрдЫ рдареАрдХ рдЪрд▓реЗрдЧрд╛ред" рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рд╣рдореЗрд╢рд╛ рдФрд░ рд╣рд░ рдЬрдЧрд╣ рд╣рд░ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдФрд░ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЕрд╡рд╕рд░ рдкрд░ рдирд╣реАрдВ рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ рдпрд╣ рдареАрдХ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдХреАрдбрд╝реЗ рдареАрдХ рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВ, рдФрд░ рдЕрдирд┐рджреНрд░рд╛ рджреВрд░ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред
рддреЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреНрдпрд╛ рд╣реИ? рд╡рд╣ рдЗрддрдиреА рдЖрдХрд░реНрд╖рдХ рдХреНрдпреЛрдВ рд╣реИ? рдФрд░ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд: рдЙрд╕рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдЧрд▓рдд рд╣реИ?
рдкрд░рд┐рдЪрдп
рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдПрдХ рдХрд╛рдлреА рд▓реЛрдХрдкреНрд░рд┐рдп рд╡рд┐рд╖рдп рд╣реИред рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрдмреЗрд░рд╛ рдХреЗ рдирд╡реАрдирддрдо рд▓реЗрдЦреЛрдВ рдХреЛ рджреЗрдЦрдирд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред рдпрд╣рд╛рдВ рдЖрдкрдХреЗ рдкрд╛рд╕ рд╡рд┐рднрд┐рдиреНрди рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ, рдФрд░ рдЧреЛ рднрд╛рд╖рд╛ рдХреЗ рдЙрдкрдпреЛрдЧ рдФрд░ рдЬреЗрдПрд╕ рдкрд░ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдврд╛рдВрдЪреЗ рдХрд╛ рдЕрд╡рд▓реЛрдХрди рд╣реИ, рдФрд░ рдмрд╣реБрдд рдХреБрдЫ рд╣реИред
рдЖрдорддреМрд░ рдкрд░, рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдиреЗрдЯрд╡рд░реНрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ shmoket рд╕реЙрдХреЗрдЯ, рдкрд╛рдардХ, рд▓реЗрдЦрдХ рдФрд░ рдЕрдиреНрдп рд╕реНрд╡реАрдХрд░реНрддрд╛ред рд▓реЗрдХрд┐рди рдЕрднреА рднреА рдЕрдЬреАрдм рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рдШрдЯрдирд╛рдПрдВ рд╣реИрдВ, рдЦрд╛рд╕рдХрд░ рдпреВрдЖрдИ рдореЗрдВред рдпрд╣рд╛рдВ рдореИрдВ рдХреЗрд╡рд▓ рдиреЗрдЯрд╡рд░реНрдХ рдЙрдкрдпреЛрдЧ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реВрдВрдЧрд╛ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЬреИрд╕рд╛ рдХрд┐ рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЕрдЬреНрдЮрд╛рдд рджреВрд░рд┐рдпреЛрдВ рдореЗрдВ рдЧрд╣рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдмрд╣реБрдд рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рд╕рд░рд▓ HTTP рд╕рд░реНрд╡рд░ рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬреЛ рдХрд┐рд╕реА рднреА рдЕрдиреБрд░реЛрдз рдкрд░ рдПрдХ рдорд╛рдирдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рднреЗрдЬрддрд╛ рд╣реИред рдпрд╣ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдПрдХ рдкрд╛рд░реНрд╕рд░ рд▓рд┐рдЦрдирд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЙрд╕рдХреЗ рдкрд╛рд╕ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЗ рд╡рд┐рд╖рдп рдХреЗ рд╕рдорд╛рди рд╣реА рд╕рдВрдмрдВрдз рд╣реИрдВ рдЬреИрд╕реЗ рдХрд┐рд╕реА рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдЪрд░рд┐рддреНрд░ рдХреЗ рд▓рд┐рдП рд╕рд┐рддрд╛рд░реЛрдВ рдХреА рд╕реНрдерд┐рддрд┐ (рдЬреНрдпреЛрддрд┐рд╖ рджреЗрдЦреЗрдВ)ред
рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рд╕рд░реНрд╡рд░
рд╣рдореНрдоред рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ? рдФрд░ рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдХрд╛ рдЗрд╕рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ, рдПрдХ рдЪреМрдХрд╕ рдкрд╛рдардХ рдкреВрдЫреЗрдЧрд╛, рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд▓реЗрдЦ рдЦреЛрд▓рдирд╛ред рдареАрдХ рд╣реИ, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рдХрд╣реАрдВ рд╢реБрд░реВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдХреБрдЫ рд╕рд░рд▓ рд╕реЗред рдФрд░ рджреВрд╕рд░реА рдмрд╛рдд ... рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдореИрдВ рд▓реЗрдЦрдХ рд╣реВрдБ, рдЗрд╕рд▓рд┐рдП рдРрд╕рд╛ рд╣реЛрдЧрд╛ред рдФрд░ рддрдм рдЖрдкрдХреЛ рдЦреБрдж рдкрддрд╛ рдЪрд▓ рдЬрд╛рдПрдЧрд╛ рдХрд┐ рдХреНрдпреЛрдВред
рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреЛрдб рдирд╣реАрдВ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рд╕рднреА рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдореИрдВ рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ
рдХрд░реВрдВрдЧрд╛, рдЬрд┐рд╕реЗ
рдмреВрд╕реНрдЯ.рдУрд╕рд┐рдпреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рд▓реЗрдЦ рдкрд╣рд▓реЗ рд╣реА рдЙрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЬрд╛ рдЪреБрдХрд╛ рд╣реИ рдХрд┐ рд╡рд╣ рд╡рд┐рд╖рдп рдореЗрдВ рдХрдо рд╕реЗ рдХрдо рдереЛрдбрд╝рд╛ рд╕рд╛ рд╣реЛред
рдлрд┐рд░ рд╕реЗ, рдХреЛрдб рдХреА рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯрддрд╛ рдФрд░ "рдЙрддреНрдкрд╛рджрди" рдХреЗ рд▓рд┐рдП, рдореИрдВ
рдмреВрд╕реНрдЯ.рд╕рд┐рдпреЛ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░реИрдкрд░
рдмрдирд╛рдКрдВрдЧрд╛ ред рдмреЗрд╢рдХ, рдХрд┐рд╕реА рдХреЛ рдлреБрдЯрдХреНрд▓реЙрде рдХреЛ
boost::asio::ip::tcp::socket
рджреЗрдирд╛ рдкрд╕рдВрдж рд╣реЛ рд╕рдХрддрд╛ рд╣реИ
boost::asio::ip::tcp::socket
рдпрд╛
boost::asio::ip::udp::resolver::iterator
, рд▓реЗрдХрд┐рди рдХреЛрдб рдХреА рд╕реНрдкрд╖реНрдЯрддрд╛ рдФрд░ рдкрдардиреАрдпрддрд╛ рдХрд╛рдлреА рдХрдо рд╣реЛ рдЬрд╛рддреА рд╣реИред
рддреЛ, рд╕реЙрдХреЗрдЯ рдФрд░ рд╕реНрд╡реАрдХрд░реНрддрд╛ рдХрд╛ рд╡рд┐рд╡рд░рдг:
typedef std::string Buffer;
рдФрд░ рдХреБрдЫ рдирд╣реАрдВ, рдмрд╕ рдПрдХ рд╕рд░реНрд╡рд░ред
Socket
рдЖрдкрдХреЛ рд▓рд┐рдЦрдиреЗ рдФрд░ рдкрдврд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдХреБрдЫ рд╡рд░реНрдгреЛрдВ рддрдХ (
readUntil
) рд╢рд╛рдорд┐рд▓ рд╣реИред
Acceptor
рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреЛрд░реНрдЯ рдкрд░ рд╕реБрдирддрд╛ рд╣реИ рдФрд░ рдХрдиреЗрдХреНрд╢рди рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред
рдЗрд╕ рдкреВрд░реА рдЕрд░реНрдерд╡реНрдпрд╡рд╕реНрдерд╛ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
boost::asio::io_service& service() { return single<boost::asio::io_service>(); } Socket::Socket() : socket(service()) { } Socket::Socket(Socket&& s) : socket(std::move(s.socket)) { } void Socket::read(Buffer& buffer) { boost::asio::read(socket, boost::asio::buffer(&buffer[0], buffer.size())); } void Socket::readSome(Buffer& buffer) { buffer.resize(socket.read_some(boost::asio::buffer(&buffer[0], buffer.size()))); } bool hasEnd(size_t posEnd, const Buffer& b, const Buffer& end) { return posEnd >= end.size() && b.rfind(end, posEnd - end.size()) != std::string::npos; } int Socket::readUntil(Buffer& buffer, const Buffer& until) { size_t offset = 0; while (true) { size_t bytes = socket.read_some(boost::asio::buffer(&buffer[offset], buffer.size() - offset)); offset += bytes; if (hasEnd(offset, buffer, until)) { buffer.resize(offset); return offset; } if (offset == buffer.size()) { LOG("not enough size: " << buffer.size()); buffer.resize(buffer.size() * 2); } } } void Socket::write(const Buffer& buffer) { boost::asio::write(socket, boost::asio::buffer(&buffer[0], buffer.size())); } void Socket::close() { socket.close(); } Acceptor::Acceptor(int port) : acceptor(service(), boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)) { } void Acceptor::accept(Socket& socket) { acceptor.accept(socket.socket); }
рдпрд╣рд╛рдБ рдореИрдВрдиреЗ
io_service
рд▓рд┐рдП рдПрдХ рд╕рд┐рдВрдЧрд▓рдЯрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ, рддрд╛рдХрд┐ рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕реЙрдХреЗрдЯ рдореЗрдВ рдЗрд╕реЗ рд╣рд░ рдмрд╛рд░ рдкрд╛рд╕ рди рдХрд░реЗрдВред рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреИрд╕реЗ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛
io_service
рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП? рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рдЗрд╕реЗ рджреВрд░ рдЫрд┐рдкрд╛ рджрд┐рдпрд╛ рддрд╛рдХрд┐ рдореЗрд░реА рдЖрдБрдЦреЗрдВ рдХреЙрд▓ рди рд╣реЛрдВред рдмрд╛рдХреА, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ,
readUntil
рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рдВрднрд╛рд╡рд┐рдд рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде, рдХрд╛рдлреА рд╕рдордЭ рдореЗрдВ
readUntil
рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рд╕рд╛рд░ рд╕рд░рд▓ рд╣реИ: рдмрд╛рдЗрдЯреНрд╕ рдХреЛ рддрдм рддрдХ рдкрдврд╝реЗрдВ рдЬрдм рддрдХ рдХрд┐ рдкреЛрд╖рд┐рдд рд╕рдорд╛рдкреНрдд рди рд╣реЛ рдЬрд╛рдПред рдпрд╣ рд╕рд┐рд░реНрдл HTTP рдХреЗ рд▓рд┐рдП рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХрд╛рд╢, рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рдЖрдХрд╛рд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рдЖрдкрдХреЛ рдЖрдХрд╛рд░ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред
рдЪрд▓рд┐рдП рдЕрдм рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдкреНрд░рддреАрдХреНрд╖рд┐рдд рд╕рд░реНрд╡рд░ рдкрд░ рд▓рд┐рдЦрддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдпрд╣ рд╣реИ:
#define HTTP_DELIM "\r\n" #define HTTP_DELIM_BODY HTTP_DELIM HTTP_DELIM
рд╕рд░реНрд╡рд░ рддреИрдпрд╛рд░ рд╣реИ!
рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдорд▓реНрдЯреАрдереНрд░реЗрдбреЗрдб рд╕рд░реНрд╡рд░
рдкрд┐рдЫрд▓реЗ рд╕рд░реНрд╡рд░ рдХреЗ рдиреБрдХрд╕рд╛рди рд╕реНрдкрд╖реНрдЯ рд╣реИрдВ:
- рдПрдХ рдмрд╛рд░ рдореЗрдВ рдХрдИ рдХрдиреЗрдХреНрд╢рди рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИред
- рдХреНрд▓рд╛рдЗрдВрдЯ рдЕрдзрд┐рдХ рдкреНрд░рднрд╛рд╡реА рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдХрдиреЗрдХреНрд╢рди рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рд╣рдо рд╣рдореЗрд╢рд╛ рдЗрд╕реЗ рдмрдВрдж рдХрд░ рджреЗрддреЗ рд╣реИрдВред
рдЗрд╕рд▓рд┐рдП, рд╡рд┐рдЪрд╛рд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрдиреЗрдХреНрд╢рдиреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реБрдП рдХрдиреЗрдХреНрд╢рди рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдереНрд░реЗрдб рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдирдпрд╛ рдзрд╛рдЧрд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдореИрдВ рдЕрдЪрд╛рдирдХ рдХреЙрд▓ рдХрд░реВрдВрдЧрд╛:
typedef std::function<void ()> Handler; void go(Handler handler) { LOG("sync::go"); std::thread([handler] { try { LOG("new thread had been created"); handler(); LOG("thread was ended successfully"); } catch (std::exception& e) { LOG("thread was ended with error: " << e.what()); } }).detach(); }
рдпрд╣ рдПрдХ рдордЬреЗрджрд╛рд░ рдмрд╛рдд рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ: рдпрджрд┐ рдЖрдк
detach()
рд╣рдЯрд╛рддреЗ
detach()
, рддреЛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдПрдВ рдХрд┐ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреНрдпрд╛ рдХрд░реЗрдЧрд╛?
рдЙрддреНрддрд░ рд╣реИ:рдпрд╣ рдореВрд░реНрдЦрддрд╛рдкреВрд░реНрдг рд░реВрдк рд╕реЗ рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╕рдВрджреЗрд╢ рдХреЗ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдорд╛рдирдХ рдХреЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдЗрд╕реЗ рдмрдирд╛рдП рд░рдЦреЗрдВ!
рдЕрдм рдЖрдк рд╕рд░реНрд╡рд░ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:
Acceptor acceptor(8800); LOG("accepting"); while (true) { Socket* toAccept = new Socket; acceptor.accept(*toAccept); LOG("accepted"); go([toAccept] { try { Socket socket = std::move(*toAccept); delete toAccept; Buffer buffer; while (true) { buffer.resize(4000); socket.readUntil(buffer, HTTP_DELIM_BODY); socket.write(httpContent("<h1>Hello sync multithread!</h1>")); } } catch (std::exception& e) { LOG("error: " << e.what()); } }); }
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдпрд╣рд╛рдВ рдирд╣реАрдВ рдерд╛: рд▓реЛрдб рдХреЗ рддрд╣рдд рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛рд░реНрдпреЛрдВ рдкрд░, рдпрд╣ рд╡реНрдпрд╡рд╕рд╛рдп рдЬрд▓реНрджреА рд╕реЗ рдЧрд┐рд░ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдмрд╛рд╣рд░ рдирд╣реАрдВ рдирд┐рдХрд▓рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╕реНрдорд╛рд░реНрдЯ рд▓реЛрдЧреЛрдВ рдиреЗ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╕реЛрдЪрд╛, рд╕реЛрдЪрд╛, рдФрд░ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред
рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕рд░реНрд╡рд░
рдкрд┐рдЫрд▓реЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рд╕рдорд╕реНрдпрд╛ рдХреНрдпрд╛ рд╣реИ? рдФрд░ рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛рдо рдХреЗ рдмрдЬрд╛рдп, рдереНрд░реЗрдб рдиреЗрдЯрд╡рд░реНрдХ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рдордп рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реИрдВ, рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдореИрдВ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдЙрдкрдпреЛрдЧреА рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдереНрд░реЗрдбреНрд╕ рдХрд╛ рдЕрдзрд┐рдХ рдХреБрд╢рд▓рддрд╛ рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред
рдЗрд╕рд▓рд┐рдП, рдореИрдВ рдЕрдм рдЗрд╕реА рддрд░рд╣ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ, рдкреНрд░реЛрдХреНрдЯрд░ рдореЙрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗред рдЗрд╕рдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ? рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╕рднреА рдСрдкрд░реЗрд╢рдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╣рдо рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдХреЙрд▓рдмреИрдХ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдСрдкрд░реЗрд╢рди рдХреЗ рдЕрдВрдд рдореЗрдВ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрд╛рдиреА рдСрдкрд░реЗрд╢рди рдкреВрд░рд╛ рд╣реЛрддреЗ рд╣реА рд╡реЗ рд╣рдореЗрдВ рдЦреБрдж рдмреБрд▓рд╛рдПрдВрдЧреЗред рдпрд╣ рд░рд┐рдПрдХреНрдЯрд░ рдореЙрдбрд▓ рд╕реЗ рднрд┐рдиреНрди рд╣реЛрддрд╛ рд╣реИ, рдЬрдм рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЛ рд╕реНрд╡рдпрдВ рдХреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рд╕рдВрдЪрд╛рд▓рди рдХреА рд╕реНрдерд┐рддрд┐ рдХрд╛ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░рдирд╛ред рд╡рд┐рд╢рд┐рд╖реНрдЯ рд░рд┐рдПрдХреНрдЯрд░ рдЙрджрд╛рд╣рд░рдг: epoll, kqueue, рдФрд░ рд╡рд┐рднрд┐рдиреНрди рдЪрдпрдиред рдкреНрд░реЛрдХреНрдЯрд░ рдЙрджрд╛рд╣рд░рдг: рд╡рд┐рдВрдбреЛрдЬ рдкрд░
IOCP ред рдореИрдВ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдмреВрд╕реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛ред
рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЗрдВрдЯрд░рдлреЗрд╕:
typedef boost::system::error_code Error; typedef std::function<void(const Error&)> IoHandler; struct Acceptor; struct Socket { friend struct Acceptor; Socket(); Socket(Socket&&); void read(Buffer&, IoHandler); void readSome(Buffer&, IoHandler); void readUntil(Buffer&, Buffer until, IoHandler); void write(const Buffer&, IoHandler); void close(); private: boost::asio::ip::tcp::socket socket; }; struct Acceptor { explicit Acceptor(int port); void accept(Socket&, IoHandler); private: boost::asio::ip::tcp::acceptor acceptor; };
рдпрд╣ рдХреБрдЫ рдЪреАрдЬреЛрдВ рдкрд░ рд░реЛрдХ рдХреЗ рд▓рд╛рдпрдХ рд╣реИ:
- рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдореЗрдВ рдЕрдм рдХрд╛рдлреА рдЕрдВрддрд░ рд╣реИред рдПрдХ рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ 2 рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ: рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЛрдб рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдпрд╛ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрдирд╛ (рдпрд╣ рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рд╡рд┐рдзрд┐ рд╣реИ)ред рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЙрд▓ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдПрдХ рд╣реА рддрд░реАрдХрд╛ рд╣реИ: рд╣реИрдВрдбрд▓рд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рддреНрд░реБрдЯрд┐ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдирд╛ред рдпрд╛рдиреА рдкрд░рд┐рдгрд╛рдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рднреА рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рд╣реИрдВрдбрд▓рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВред рдФрд░ рдЕрдЧрд░ рдЖрдк рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдпрджрд┐ рдЖрдк рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЕрдЪреНрдЫреЗ рдкреБрд░рд╛рдиреЗ рджрд┐рдиреЛрдВ рдХреА рддрд░рд╣ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд░рд╣реЗрдВ, рдЬрдм рдХреЛрдИ рдЕрдкрд╡рд╛рдж рдирд╣реАрдВ рдереЗ: рд╣рд░ рдПрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪреЗрдХ рдерд╛ред рд▓реЗрдХрд┐рди рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк, рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рдпрд╣ рдирд╣реАрдВ рд╣реИ; рджрд┐рд▓рдЪрд╕реНрдк рдпрд╣ рд╣реИ рдХрд┐ рдЬрдм рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реБрдИ рдФрд░ рдЙрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╕рдВрджрд░реНрдн рдХреЛ рдпрд╛рдж рдХрд░рдирд╛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд╛ рдПрдХ рдкрд╕рдВрджреАрджрд╛ рдХрд╛рд░реНрдп рд╣реИ!
- рдПрдХ рд╕реБрд╕рдВрдЧрдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ
IoHandler
рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛, рдЬреЛ рдХреЛрдб рдХреЛ рд╕рд░рд▓ рдФрд░ рдЕрдзрд┐рдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдмрдирд╛рддрд╛ рд╣реИред
рдпрджрд┐ рдЖрдк рдмрд╛рд░реАрдХреА рд╕реЗ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдлрд╝рдВрдХреНрд╢рдВрд╕ рд╕реЗ рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдореЗрдВ рдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рд╣реИрдВрдбрд▓рд░ рд╣реЛрддрд╛ рд╣реИред
рдЦреИрд░, рдЪрд┐рдВрддрд╛ рдХреА рдХреЛрдИ рдмрд╛рдд рдирд╣реАрдВ рд╣реИред
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:
Socket::Socket() : socket(service()) { } Socket::Socket(Socket&& s) : socket(std::move(s.socket)) { } void Socket::read(Buffer& buffer, IoHandler handler) { boost::asio::async_read(socket, boost::asio::buffer(&buffer[0], buffer.size()), [&buffer, handler](const Error& error, std::size_t) { handler(error); }); } void Socket::readSome(Buffer& buffer, IoHandler handler) { socket.async_read_some(boost::asio::buffer(&buffer[0], buffer.size()), [&buffer, handler](const Error& error, std::size_t bytes) { buffer.resize(bytes); handler(error); }); } bool hasEnd(size_t posEnd, const Buffer& b, const Buffer& end) { return posEnd >= end.size() && b.rfind(end, posEnd - end.size()) != std::string::npos; } void Socket::readUntil(Buffer& buffer, Buffer until, IoHandler handler) { VERIFY(buffer.size() >= until.size(), "Buffer size is smaller than expected"); struct UntilHandler { UntilHandler(Socket& socket_, Buffer& buffer_, Buffer until_, IoHandler handler_) : offset(0), socket(socket_), buffer(buffer_), until(std::move(until_)), handler(std::move(handler_)) { } void read() { LOG("read at offset: " << offset); socket.socket.async_read_some(boost::asio::buffer(&buffer[offset], buffer.size() - offset), *this); } void complete(const Error& error) { handler(error); } void operator()(const Error& error, std::size_t bytes) { if (!!error) { return complete(error); } offset += bytes; VERIFY(offset <= buffer.size(), "Offset outside buffer size"); LOG("buffer: '" << buffer.substr(0, offset) << "'"); if (hasEnd(offset, buffer, until)) {
readUntil
рдкрджреНрдзрддрд┐ рдХреЛ рдЫреЛрдбрд╝рдХрд░, рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдПрдХ рд╕реЙрдХреЗрдЯ рдкрд░ рдХрдИ рдмрд╛рд░ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реАрдбреНрд╕ рдХреЛ рдЖрдордВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд░рд╛рдЬреНрдп рдХреЛ рдмрдирд╛рдП рд░рдЦрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╡рд░реНрдЧ
UntilHandler
рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдСрдкрд░реЗрд╢рди рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрдЪрд╛рддрд╛ рд╣реИред рдЗрд╕реА рддрд░рд╣ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд╡рд┐рднрд┐рдиреНрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП
boost.asio рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
boost::asio::read
) рдЬрд┐рд╕рдореЗрдВ рд╕рд░рд▓ (рд▓реЗрдХрд┐рди рдХреЛрдИ рдХрдо рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ) рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП рдХрдИ рдХреЙрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдкрдХреЛ
go
рдФрд░ рдкреНрд░реЗрд╖рдг рдХрд╛ рдПрдХ рдПрдирд╛рд▓реЙрдЧ рд▓рд┐рдЦрдирд╛
go
:
void go(Handler); void dispatch(int threadCount = 0);
рдпрд╣рд╛рдВ рдЖрдк рдПрдХ рд╣реИрдВрдбрд▓рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рдереНрд░реЗрдб рдкреВрд▓ рдореЗрдВ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдПрдХ рд╢реЗрдбреНрдпреВрд▓рд┐рдВрдЧ рд╢реЗрдбреНрдпреВрд▓рд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдереНрд░реЗрдб рдкреВрд▓ рдХрд╛ рдирд┐рд░реНрдорд╛рдгред
рдпрд╣рд╛рдВ рдпрд╣ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:
void go(Handler handler) { LOG("async::go"); service().post(std::move(handler)); } void run() { service().run(); } void dispatch(int threadCount) { int threads = threadCount > 0 ? threadCount : int(std::thread::hardware_concurrency()); RLOG("Threads: " << threads); for (int i = 1; i < threads; ++ i) sync::go(run); run(); }
рдпрд╣рд╛рдВ рд╣рдо
sync::go
рдЙрдкрдпреЛрдЧ
sync::go
рдПрдХ рд╕рдордХрд╛рд▓рд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдзрд╛рдЧреЗ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП
sync::go
ред
рд╕рд░реНрд╡рд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:
Acceptor acceptor(8800); LOG("accepting"); Handler accepting = [&acceptor, &accepting] { struct Connection { Buffer buffer; Socket socket; void handling() { buffer.resize(4000); socket.readUntil(buffer, HTTP_DELIM_BODY, [this](const Error& error) { if (!!error) { LOG("error on reading: " << error.message()); delete this; return; } LOG("read"); buffer = httpContent("<h1>Hello async!</h1>"); socket.write(buffer, [this](const Error& error) { if (!!error) { LOG("error on writing: " << error.message()); delete this; return; } LOG("written"); handling(); }); }); } }; Connection* conn = new Connection; acceptor.accept(conn->socket, [conn, &accepting](const Error& error) { if (!!error) { LOG("error on accepting: " << error.message()); delete conn; return; } LOG("accepted"); conn->handling(); accepting(); }); }; accepting(); dispatch();

рдпрд╣рд╛рдБ рдПрдХ рдЪрд╛рджрд░ рд╣реИред рд╣рд░ рдирдИ рдЪреБрдиреМрддреА рдХреЗ рд╕рд╛рде, рд▓рдВрдмреЛрджрд░ рдХрд╛ рдШреЛрдВрд╕рд▓рд╛ рдмрдврд╝ рд░рд╣рд╛ рд╣реИред рдЖрдорддреМрд░ рдкрд░, рдмреЗрд╢рдХ, рдпрд╣ рд▓реИрдореНрдмреНрдбрд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдирд╣реАрдВ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд▓реВрдк рдХреЗ рд╕рд╛рде рдХрдард┐рдирд╛рдЗрдпрд╛рдБ рд╣реИрдВ: рд▓реИрдореНрдмреНрдбрд╛ рдореЗрдВ рдЖрдкрдХреЛ рдЦреБрдж рдХреЛ рдЕрдкрдиреЗ рдЕрдВрджрд░ рдмреБрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЦреБрдж рдХреЛ рдлреЗрдВрдХрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред рдлрд┐рд░ рднреА, рдХреЛрдб рдХреА рдкрдардиреАрдпрддрд╛ рд▓рдЧрднрдЧ рд╕рдорд╛рди рд╣реЛрдЧреА, рдЕрд░реНрдерд╛рддред рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдмреБрд░рд╛ рдЬрдм рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЛрдб рдХреА рддреБрд▓рдирд╛ рдореЗрдВред
рддреЛ, рдЪрд▓реЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдкреЗрд╢реЗрд╡рд░реЛрдВ рдФрд░ рд╡рд┐рдкрдХреНрд╖реЛрдВ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рддреЗ рд╣реИрдВ:
- рдПрдХ рдирд┐рд░рдкреЗрдХреНрд╖ рдкреНрд▓рд╕ (рдФрд░ рдпрд╣, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рд╕рдм рдкреАрдбрд╝рд╛ рдХреЗ рд▓рд┐рдП рд╣реИ) - рдЙрддреНрдкрд╛рджрдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рд╕рд┐рд░реНрдл рдХрдИ рдЧреБрдирд╛ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдкрд░рд┐рдорд╛рдг рдХреЗ рдЖрджреЗрд╢реЛрдВ рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ!
- рдЦреИрд░, рдЕрдм рдЕрдВрддред рдареАрдХ рдПрдХ рдорд╛рдЗрдирд╕ рд╣реИ - рдЬрдЯрд┐рд▓ рдФрд░ рднреНрд░рд╛рдордХ рдХреЛрдб, рдЬрд┐рд╕реЗ рдбрд┐рдмрдЧ рдХрд░рдирд╛ рднреА рдореБрд╢реНрдХрд┐рд▓ рд╣реИред
рдареАрдХ рд╣реИ, рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рдЕрдЧрд░ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдпрд╣ рддреБрд░рдВрдд рдФрд░ рдмрдЧ рдХреЗ рдмрд┐рдирд╛ рдХрд╛рдо рдХрд┐рдпрд╛ред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ ... рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ, рдЦреБрд╢ рдбрд┐рдмрдЧрд┐рдВрдЧ, рдЬреИрд╕рд╛ рдХрд┐ рд╡реЗ рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдХрд╣рддреЗ рд╣реИрдВред рдФрд░ рдореИрдВрдиреЗ рдЗрд╕ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдХреА рднреА рдЬрд╛рдВрдЪ рдХреА, рдЬрд╣рд╛рдВ рдЖрдк рдХреЙрд▓ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рдЯреНрд░реИрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдпреЛрдЬрдирд╛ рдХреА рдереЛрдбрд╝реА рд╕реА рдЬрдЯрд┐рд▓рддрд╛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╕рд╛рде рдкрдврд╝рдиреЗ рдФрд░ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЙрдХреЗрдЯреНрд╕) рдХреЗ рд╕рд╛рде, рдХреЛрдб рдХреА рдЬрдЯрд┐рд▓рддрд╛ рдЫрд▓рд╛рдВрдЧ рдФрд░ рд╕реАрдорд╛ рд╕реЗ рдмрдврд╝рддреА рд╣реИ, рдФрд░ рдмрдЧ рдХреА рд╕рдВрдЦреНрдпрд╛ рд▓рдЧрднрдЧ рддреЗрдЬрд╝реА рд╕реЗ рдмрдврд╝рдиреЗ рд▓рдЧрддреА рд╣реИред
рддреЛ рдХреНрдпрд╛ рдореЛрдордмрддреНрддреА рдХреЗ рд▓рд╛рдпрдХ рдЦреЗрд▓ рд╣реИ? рдХреНрдпрд╛ рдореБрдЭреЗ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕реА рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП? рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рд░рд╛рд╕реНрддрд╛ рд╣реИ - рдХреЛрд░рдЯрд╛рдЗрди рдпрд╛
рдХреЛрд░рдЖрдЙрдЯ ред
coroutine
рддреЛ рд╣рдо рд╕рдм рдХреНрдпрд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?
рдЦреБрд╢реА, рд╕реНрд╡рд╛рд╕реНрдереНрдп, рдордиреА рдмреИрдЧред рд▓реЗрдХрд┐рди рдореИрдВ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЪрд╛рд╣рддрд╛ рд╣реВрдВ: рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдФрд░ рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдлрд╛рдпрджреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдЕрд░реНрдерд╛рддреНред рддрд╛рдХрд┐ рдкреНрд░рджрд░реНрд╢рди рджреЛрдиреЛрдВ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдФрд░ рд╕рд╛рджрдЧреА рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╣реЛред
рдХрд╛рдЧрдЬ рдкрд░ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд▓рдЧрддрд╛ рд╣реИред рдХреНрдпрд╛ рдпрд╣ рд╕рдВрднрд╡ рд╣реИ? рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рд▓рд┐рдП рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдкрд░рд┐рдЪрдп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдирд┐рдпрдорд┐рдд рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ рдХреНрдпрд╛ рд╣реИрдВ? рдЗрд╕рд▓рд┐рдП, рд╣рдо рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдХрд┐рд╕реА рд╕реНрдерд╛рди рдкрд░ рдФрд░ рдпрд╣рд╛рдБ рдлрд┐рд░ рд╕реЗ, рдФрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдХрд╣рддреЗ рд╣реИрдВред рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд▓реМрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд░реНрддрдорд╛рди рд╕реНрдерд╛рди рдХреЛ рдкрд╣рд▓реЗ рдпрд╛рдж рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдлрд┐рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдкреВрд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЙрд╕ рд╕реНрдерд╛рди рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рд▓реМрдЯрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рд╕реЗ рдЗрд╕реЗ рдмреБрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдФрд░ рдХреЛрд░рдЯрд╛рдЗрди рдПрдХ рд╣реА рд╣реИ, рдХреЗрд╡рд▓ рднрд┐рдиреНрди: рдпрд╣ рдЙрд╕ рд╕реНрдерд╛рди рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рднреА рд▓реМрдЯрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рд╕реЗ рдЗрд╕реЗ рдмреБрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдпрд╣
рд╕рдорд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ , рд▓реЗрдХрд┐рди рдХреБрдЫ рдЬрдЧрд╣ рдкрд░ рдмрдВрдж рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рд╕реЗ рдкреБрдирд░рд╛рд░рдВрдн рд╣реЛрдиреЗ рдкрд░ рдпрд╣ рдХрд╛рдо рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦрддрд╛ рд╣реИред рдпрд╛рдиреА рдпрд╣ рдПрдХ рддрд░рд╣ рдХрд╛ рдкрд┐рдВрдЧ-рдкреЛрдВрдЧ рдирд┐рдХрд▓рддрд╛ рд╣реИ: рдХреЙрд▓ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдЧреЗрдВрдж рдХреЛ рдлреЗрдВрдХрддрд╛ рд╣реИ, рдХреЛрд░рдЯрд╛рдЗрди рдЙрд╕реЗ рдкрдХрдбрд╝рддрд╛ рд╣реИ, рджреВрд╕рд░реА рдЬрдЧрд╣ рдЪрд▓рд╛рддрд╛ рд╣реИ, рдЙрд╕реЗ рд╡рд╛рдкрд╕ рдлреЗрдВрдХрддрд╛ рд╣реИ, рдХреЙрд▓ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдХреБрдЫ рдХрд░рддрд╛ рд╣реИ (рдУрд╡рд░ рдЪрд▓рд╛рддрд╛ рд╣реИ) рдФрд░ рдкрд┐рдЫрд▓реЗ рд╕реНрдерд╛рди рдкрд░ рд╡рд╛рдкрд╕ рдХреЛрд░рдЖрдЙрдЯ рдХреЛ рдлреЗрдВрдХрддрд╛ рд╣реИред рдФрд░ рдпрд╣ рддрдм рддрдХ рд╣реЛрддрд╛ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдХреЛрд░реЛрдЗрди рдкреВрд░рд╛ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╣рдо рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдПрдХ рдХреЛрд░рдЯрд╛рдЗрди рдХрд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓рд╛ рд╣реИред
рдЕрдм рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдорд╛рд░реЗ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ? рдЦреИрд░, рдпрд╣рд╛рдБ рдпрд╣ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреЛрд░рдЯрд╛рдЗрди рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдирд┐рд╖реНрдкрд╛рджрди рд╕рдВрджрд░реНрдн рд░рдЦрддрд╛ рд╣реИ, рдЬреЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЗ рд▓рд┐рдП рдЕрддреНрдпрдВрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рдореИрдВ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛: рдпрджрд┐ рдХреЛрд░рдЯрд╛рдЗрди рдХреЛ рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдСрдкрд░реЗрд╢рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдореИрдВ рдмрд╕ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рдХреЛрд░рдЯрд╛рдЗрди рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддрд╛ рд╣реВрдВред рдФрд░ рд╣реИрдВрдбрд▓рд░, рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдСрдкрд░реЗрд╢рди рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдкрд░, рдмрд╕ рдЙрд╕ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдСрдкрд░реЗрд╢рди рдХреЗ рдЕрдВрддрд┐рдо рдХреЙрд▓ рдХреЗ рд╕реНрдерд╛рди рд╕реЗ рд╣рдорд╛рд░реЗ рдХреЛрд░рдЖрдЙрдЯ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦреЗрдЧрд╛ред рдпрд╛рдиреА рд╕рдВрджрд░реНрдн рдХреЛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд╕рднреА рдЧрдВрджреЗ рдХрд╛рдо рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдЯрд┐рдХреА рд╣реБрдИ рд╣реИред
рдФрд░ рдпрд╣реАрдВ рд╕реЗ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИрдВред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рднрд╛рд╖рд╛рдУрдВ рдФрд░ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреА рдУрд░ рд╕реЗ рдХреЛрд░рдЯрд╛рдЗрди рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдирд╛ рдмреАрддреЗ рджрд┐рдиреЛрдВ рдХреА рдмрд╛рдд рд╣реИред рдЖрдЬ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдВрджрд░реНрднреЛрдВ рдХреЗ рд╕реНрд╡рд┐рдЪрд┐рдВрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрдИ рдСрдкрд░реЗрд╢рди рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ: рд░рдЬрд┐рд╕реНрдЯрд░ рдЕрд╡рд╕реНрдерд╛рдУрдВ рдХреЛ рдмрдЪрд╛рдиреЗ, рд╕реНрдЯреИрдХ рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдФрд░ рд░рдирдЯрд╛рдЗрдо рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕реЗрд╡рд╛ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднрд░реЗрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЕрдкрд╡рд╛рдж,
рдЯреАрдПрд▓рдПрд╕ , рдЖрджрд┐ рдХреЗ рд▓рд┐рдП)ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рди рдХреЗрд╡рд▓ рдкреНрд░реЛрд╕реЗрд╕рд░ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рдФрд░ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдкрд░ рднреА рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред рддрд╛рдмреВрдд рдХреЗ рдврдХреНрдХрди рдореЗрдВ рдЖрдЦрд┐рд░реА рдХреАрд▓ рдХреА рддрд░рд╣ рд▓рдЧрддрд╛ рд╣реИ ...
рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рд╡рд╣рд╛рдБ
boost.context рд╣реИ , рдЬреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рднреА рдЪреАрдЬреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рд╕рдм рдХреБрдЫ рдЕрд╕реЗрдВрдмрд▓рд░ рдореЗрдВ, рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреА рдкрд░рдВрдкрд░рд╛ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИред рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ,
рдмреВрд╕реНрдЯ.рдХреЙрд░рдЯрд╛рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХреНрдпреЛрдВ, рдХрдм рдХрдм рд╣реИред рдЕрдзрд┐рдХ рдирд░рдХ рдФрд░ рдЬрд▓рд╛!
Coroutine рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрдкрдиреЗ рдХреЛрд░рдЖрдЙрдЯреНрд╕ рдХреЛ рд▓рд┐рдЦреЗрдВрдЧреЗред рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧрд╛:
рдпрд╣рд╛рдБ рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рд╕рд░рд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИред рдЦреИрд░, рддреБрд░рдВрдд, рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓рд╛:
void coro() { std::cout << '2'; yield(); std::cout << '4'; }
std::cout << '1'; Coro c(coro); std::cout << '3'; c.resume(); std::cout << '5';
рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП:
12345
рдЪрд▓реЛ
start
рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде
start
рдХрд░рддреЗ рд╣реИрдВ:
void Coro::start(Handler handler) { VERIFY(!isStarted(), "Trying to start already started coro"); context = boost::context::make_fcontext(&stack.back(), stack.size(), &starterWrapper0); jump0(reinterpret_cast<intptr_t>(&handler)); }
рдпрд╣рд╛рдБ
boost::context::make_fcontext
рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдПрдХ рд╕рдВрджрд░реНрдн рдмрдирд╛рддрд╛ рд╣реИ рдФрд░
starterWrapper0
рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ
starterWrapper0
рд╕реНрдерд┐рд░ рд╡рд┐рдзрд┐ рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ:
TLS Coro* t_coro; void Coro::starterWrapper0(intptr_t p) { t_coro->starter0(p); }
рдЬреЛ рдмрд╕
starter0
рдкрджреНрдзрддрд┐ рдХреЛ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ,
рдЯреАрдПрд▓рдПрд╕ рд╕реЗ рд╡рд░реНрддрдорд╛рди
Coro
рдЙрджрд╛рд╣рд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рд╕рдВрджрд░реНрднреЛрдВ рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХрд╛ рд╕рд╛рд░рд╛ рдЬрд╛рджреВ рдирд┐рдЬреА
jump0
рд╡рд┐рдзрд┐ рдореЗрдВ рд╣реИ:
void Coro::jump0(intptr_t p) { Coro* old = this; std::swap(old, t_coro); running = true; boost::context::jump_fcontext(&savedContext, context, p); running = false; std::swap(old, t_coro); if (exc != std::exception_ptr()) std::rethrow_exception(exc); }
рдпрд╣рд╛рдВ рд╣рдо рдкреБрд░рд╛рдиреЗ
рдЯреАрдПрд▓рдПрд╕ t_coro
рдорд╛рди
t_coro
рдПрдХ рдирдП (рдХрдИ
t_coro
рдмреАрдЪ рдкреБрдирд░рд╛рд╡рд░реНрддреА рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛) рдХреЗ
t_coro
рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЭрдВрдбреЗ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╕рдВрджрд░реНрдн рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рд╕рдВрджрд░реНрдн рдХреЛ
boost::context::jump_fcontext
ред рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдкреБрд░рд╛рдиреЗ рдорд╛рдиреЛрдВ рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдХреЙрд▓рд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдлреЗрдВрдХ рджреЗрддреЗ рд╣реИрдВред
рдЕрдм рд╣рдо рдирд┐рдЬреА рд╡рд┐рдзрд┐
starter0
, рдЬреЛ рд╡рд╛рдВрдЫрд┐рдд рд╣реИрдВрдбрд▓рд░ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИ:
void Coro::starter0(intptr_t p) { started = true; try { Handler handler = std::move(*reinterpret_cast<Handler*>(p)); handler(); } catch (...) { exc = std::current_exception(); } started = false; yield0(); }
рдореИрдВ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд рдкрд░ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ: рдпрджрд┐ рдЖрдк рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рдЕрдВрджрд░ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдирд╣реАрдВ рдмрдЪрд╛рддреЗ рд╣реИрдВ (рдЗрд╕реЗ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ) рд╕реЗ рдкрд╣рд▓реЗ, рддреЛ рдмрд╛рдж рдореЗрдВ рд▓реМрдЯрдиреЗ рдкрд░, рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдХреНрд░реИрд╢ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рд╣реИ рдХрд┐, рдЖрдо рддреМрд░ рдкрд░ рдмреЛрд▓рдирд╛, рд╣реИрдВрдбрд▓рд░ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рдХреБрдЫ рд░рд╛рдЬреНрдп рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдХреБрдЫ рдмрд┐рдВрджреБ рдкрд░ рдирд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЕрдм рд╢реЗрд╖ рдХрд╛рд░реНрдпреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рд╢реЗрд╖ рд╣реИ:
Synca: async рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд
рдЕрдм рдХреЛрд░рдЯрд╛рдЗрди рдкрд░ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдмрд╛рд░реА рд╣реИред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЖрд░реЗрдЦ рдореЗрдВ рдПрдХ рддреБрдЪреНрдЫ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рдХрд▓реНрдк рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:
рдпрд╣рд╛рдВ, рдХреЛрд░рдЯрд╛рдЗрди рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдлрд┐рд░ рдХреЛрд░рдЯрд╛рдЗрди рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдСрдкрд░реЗрд╢рди рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИ рдФрд░
yield()
рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддрд╛ рд╣реИред рдСрдкрд░реЗрд╢рди рдкреВрд░рд╛ рд╣реЛрдиреЗ рдкрд░, рдХреЙрдЯрд╛рдЙрдЗрди
resume()
рд╕реЗ
resume()
рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдХрд╛рдо рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦрддрд╛ рд╣реИред
рдФрд░ рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдХреБрдЦреНрдпрд╛рдд рдорд▓реНрдЯреАрдереНрд░реЗрдбрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВред рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рдпрд╣ рдХреБрдЫ рдЕрд╢рд╛рдВрддрд┐ рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЙрдкрд░реЛрдХреНрдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рдареАрдХ рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдирд┐рдореНрди рдЪрд┐рддреНрд░ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджрд┐рдЦрд╛рддрд╛ рд╣реИ:

рдпрд╛рдиреА рдСрдкрд░реЗрд╢рди рдХреЗ рд╢реЗрдбреНрдпреВрд▓рд┐рдВрдЧ рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж, рдПрдХ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдХреЛрд░рдЯрд╛рдЗрди рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рддрдХ рдирд┐рд╖реНрдкрд╛рджрди рдЬрд╛рд░реА рд░рдЦреЗрдЧрд╛ред рдпрд╣, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рд╣рдорд╛рд░реА рдпреЛрдЬрдирд╛рдУрдВ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдирд╣реАрдВ рдерд╛ред рдЗрд╕рд▓рд┐рдП, рдЖрдкрдХреЛ рдЕрдиреБрдХреНрд░рдо рдХреЛ рдЬрдЯрд┐рд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:
рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдХреЛрд░рдЯрд╛рдЗрди рдореЗрдВ рд╢реЗрдбрд┐рдВрдЧ рд╢реБрд░реВ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдмрд╛рд╣рд░, рдЬреЛ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рд╕рдВрднрд╛рд╡рдирд╛ рдХреЛ рдмрд╛рд╣рд░ рдХрд░рддрд╛ рд╣реИред
рдЗрд╕реА рд╕рдордп, рдХреЙрд░рдЯреАрди рдХреА рдирд┐рд░рдВрддрд░рддрд╛ рдПрдХ рдФрд░ рдзрд╛рдЧреЗ рдореЗрдВ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдЬреЛ рдХрд┐ рдХрд╛рдлреА рд╕рд╛рдорд╛рдиреНрдп рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реИ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреЛрд░рдЯрд╛рдЗрди рдХреЛ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рдмрдирд╛рдП рд░рдЦрддреЗ рд╣реБрдП, рдЙрдиреНрд╣реЗрдВ рдЖрдЧреЗ рдФрд░ рдкреАрдЫреЗ рд▓рдЯрдХрд╛рдП рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИредрдЫреЛрдЯреА рдЯрд┐рдкреНрдкрдгреА,
boost.asio .
io_service::strand
, . - , тАж , , .
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
рдЪрд▓реЛ рд╕рдорд╛рд░реЛрд╣ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ go
: void go(Handler handler) { LOG("synca::go"); async::go([handler] { coro::Coro* coro = new coro::Coro(std::move(handler)); onCoroComplete(coro); }); }
рдпрд╣рд╛рдВ, рдХреЗрд╡рд▓ рд╣реИрдВрдбрд▓рд░ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдПрдХ рдХреЛрд░рдЯрд╛рдЗрди рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕рдХреЗ рдЕрдВрджрд░ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣рд╛рдВ рдмреНрдпрд╛рдЬ рднреА рдПрдХ рдРрд╕рд╛ рдХрд╛рд░реНрдп рд╣реИ onCoroComplete
рдЬреЛ рджреЗрдЦрдиреЗ рдореЗрдВ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдордЬрд╝рд╛рдХ рдХрд░рдирд╛ рд╣реИ: typedef std::function<void(coro::Coro*)> CoroHandler; TLS CoroHandler* t_deferHandler; void onCoroComplete(coro::Coro* coro) { VERIFY(!coro::isInsideCoro(), "Complete inside coro"); VERIFY(coro->isStarted() == (t_deferHandler != nullptr), "Unexpected condition in defer/started state"); if (t_deferHandler != nullptr) { LOG("invoking defer handler"); (*t_deferHandler)(coro); t_deferHandler = nullptr; LOG("completed defer handler"); } else { LOG("nothing to do, deleting coro"); delete coro; } }
рдХреНрд░рд┐рдпрд╛рдПрдВ рд╕рд░рд▓ рд╣реИрдВ: рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рдХреБрдЫ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИред рдЕрдЧрд░ рд╡рд╣рд╛рдБ рд╣реИ - рддреЛ рд╣рдо рдЗрд╕реЗ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдирд╣реАрдВ - рддреЛ рдХреЛрд░рдЯрд╛рдЗрди рдиреЗ рдЕрдкрдирд╛ рдХрд╛рдо рдЦрддреНрдо рдХрд░ рджрд┐рдпрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╣рдЯрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИредрд╕рд╡рд╛рд▓ рдЙрдарддрд╛ рд╣реИ: рдпрд╣ рдХреИрд╕реЗ рднрд░рд╛ рдЬрд╛рддрд╛ рд╣реИ t_deferHandler
? рдФрд░ рдЗрд╕рд▓рд┐рдП:
TLS const Error* t_error; void handleError() { if (t_error) throw boost::system::system_error(*t_error, "synca"); } void defer(CoroHandler handler) { VERIFY(coro::isInsideCoro(), "defer() outside coro"); VERIFY(t_deferHandler == nullptr, "There is unexecuted defer handler"); t_deferHandler = &handler; coro::yield(); handleError(); }
рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╣рдореЗрд╢рд╛ рдПрдХ рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рдЕрдВрджрд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣рд╛рдВ, рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╣реИрдВрдбрд▓рд░ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рд╕рдВрдЪрд╛рд▓рди рдмрд╣рд╛ рд╕реЗ рдирд┐рдкрдЯреЗрдЧрд╛, рдЕрд░реНрдерд╛рддреНред рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЪрд▓ рд░рд╣рд╛ рд╣реИред рдЗрд╕ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдпрд╛рдж рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЗрд╕реЗ рдХреЛрд░рдЯрд╛рдЗрди ( coro::yield
) рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдкрд░ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ , рдпрд╣ рддреБрд░рдВрдд рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдХреЗ рдмрд╛рдж рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ onCoroComplete
, рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рдВрдмрд┐рдд рд╣реИрдВрдбрд▓рд░ рдХреЛ рд▓реЙрдиреНрдЪ рдХрд░рддрд╛ рд╣реИ ред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдорд╛рд░реЛрд╣ рдХрд╛ рдПрдХ рдкреНрд░рдпреЛрдЧ рд╣реИ defer
рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк Socket::accept
: void onComplete(coro::Coro* coro, const Error& error) { LOG("async completed, coro: " << coro << ", error: " << error.message()); VERIFY(coro != nullptr, "Coro is null"); VERIFY(!coro::isInsideCoro(), "Completion inside coro"); t_error = error ? &error : nullptr; coro->resume(); LOG("after resume"); onCoroComplete(coro); } async::IoHandler onCompleteHandler(coro::Coro* coro) { return [coro](const Error& error) { onComplete(coro, error); }; } void Acceptor::accept(Socket& socket) { VERIFY(coro::isInsideCoro(), "accept must be called inside coro"); defer([this, &socket](coro::Coro* coro) { VERIFY(!coro::isInsideCoro(), "accept completion must be called outside coro"); acceptor.accept(socket.socket, onCompleteHandler(coro)); LOG("accept scheduled"); }); }
onCompleteHandler
рдПрдХ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╣реИрдВрдбрд▓рд░ рд▓реМрдЯрд╛рддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдСрдкрд░реЗрд╢рди рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред рд╣реИрдВрдбрд▓рд░ рдХреЗ рдЕрдВрджрд░ рдПрдХ рддреНрд░реБрдЯрд┐ рд╕рдВрдЧреНрд░рд╣реАрдд рдХреА рдЬрд╛рддреА рд╣реИ t_error
рддрд╛рдХрд┐ рдмрд╛рдж рдореЗрдВ рд╣рдорд╛рд░реЗ рдХреЙрд░рдЯреАрди рдХреЗ рдЕрдВрджрд░ рдПрдХ рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛ ( handleError
рдЕрдВрджрд░ рдХреЙрд▓ рджреЗрдЦреЗрдВ defer
), рдФрд░ рдлрд┐рд░ рдХреЙрд░рдЯреАрди рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рдЬрд╛рд░реА рд░рдЦреЗрдВ coro->resume()
, рдЕрд░реНрдерд╛рддред defer
рдХреЙрд▓ рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж рд╡рд┐рдзрд┐ рдкрд░ рд▓реМрдЯреЗрдВ yield()
ред рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЖрд░реЗрдЦ рдХреЙрд▓ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдФрд░ рд╡рд┐рднрд┐рдиреНрди рд╕рдВрд╕реНрдерд╛рдУрдВ рдХреА рдмрд╛рддрдЪреАрдд рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ:рдЕрдиреНрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЗрд╕реА рддрд░рд╣ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: void Socket::readSome(Buffer& buffer) { VERIFY(coro::isInsideCoro(), "readSome must be called inside coro"); defer([this, &buffer](coro::Coro* coro) { VERIFY(!coro::isInsideCoro(), "readSome completion must be called outside coro"); socket.readSome(buffer, onCompleteHandler(coro)); LOG("readSome scheduled"); }); } void Socket::readUntil(Buffer& buffer, Buffer until) { VERIFY(coro::isInsideCoro(), "readUntil must be called inside coro"); defer([this, &buffer, until](coro::Coro* coro) { VERIFY(!coro::isInsideCoro(), "readUntil completion must be called outside coro"); socket.readUntil(buffer, std::move(until), onCompleteHandler(coro)); LOG("readUntil scheduled"); }); } void Socket::write(const Buffer& buffer) { VERIFY(coro::isInsideCoro(), "write must be called inside coro"); defer([this, &buffer](coro::Coro* coro) { VERIFY(!coro::isInsideCoro(), "write completion must be called outside coro"); socket.write(buffer, onCompleteHandler(coro)); LOG("write scheduled"); }); }
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рд╣рд░ рдЬрдЧрд╣, рдореИрдВ рдЗрд╕реА рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ async::Socket
рдФрд░ async::Acceptor
, рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдкрд░ рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИредрдХреЗ рдЙрдкрдпреЛрдЧ
рдЕрдкрдиреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рд╣реИ: Acceptor acceptor(8800); LOG("accepting"); go([&acceptor] { while (true) { Socket* toAccept = new Socket; acceptor.accept(*toAccept); LOG("accepted"); go([toAccept] { try { Socket socket = std::move(*toAccept); delete toAccept; Buffer buffer; while (true) { buffer.resize(4000); socket.readUntil(buffer, HTTP_DELIM_BODY); socket.write(httpContent("<h1>Hello synca!</h1>")); } } catch (std::exception& e) { LOG("error: " << e.what()); } }); } }); dispatch();
рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдХреБрдЫ рд╣рдж рддрдХ рдпрд╛рдж рджрд┐рд▓рд╛рддрд╛ рд╣реИ ... рдмрд┐рд▓реНрдХреБрд▓! рдпрд╣ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рд╣рдорд╛рд░рд╛ рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЛрдб рд╣реИ:sync | synca |
---|
Acceptor acceptor(8800); LOG("accepting"); while (true) { Socket* toAccept = new Socket; acceptor.accept(*toAccept); LOG("accepted"); go([toAccept] { try { Socket socket = std::move(*toAccept); delete toAccept; Buffer buffer; while (true) { buffer.resize(4000); socket.readUntil(buffer, HTTP_DELIM_BODY); socket.write(httpContent( "<h1>Hello sync multithread!</h1>")); } } catch (std::exception& e) { LOG("error: " << e.what()); } }); } | Acceptor acceptor(8800); LOG("accepting"); go([&acceptor] { while (true) { Socket* toAccept = new Socket; acceptor.accept(*toAccept); LOG("accepted"); go([toAccept] { try { Socket socket = std::move(*toAccept); delete toAccept; Buffer buffer; while (true) { buffer.resize(4000); socket.readUntil(buffer, HTTP_DELIM_BODY); socket.write(httpContent( "<h1>Hello synca!</h1>")); } } catch (std::exception& e) { LOG("error: " << e.what()); } }); } }); dispatch(); |
рдмрд┐рд▓реНрдХреБрд▓ рдПрдХ рдЕрдВрддрд░ рд╣реИ: рдПрдХ рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рд╕реЙрдХреЗрдЯ рдХреЛ рдЕрдкрдирд╛рдирд╛ рдореБрдЦреНрдп рдзрд╛рдЧреЗ рдореЗрдВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рд▓рд┐рдП рдЕрдиреБрдкрд╕реНрдерд┐рдд рд╣реИ dispatch
ред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрджрд┐ рдХреЛрдИ рд▓рдХреНрд╖реНрдп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ, рддреЛ рдХреЛрдИ рднреА рдЗрди рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕рдорд╛рди рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИ: рдЗрд╕рдХреЗ рд▓рд┐рдП, рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рдПрдХ рдЕрд▓рдЧ рдереНрд░реЗрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реЙрдХреЗрдЯреНрд╕ рдХреЛ рднреА рдЕрдкрдирд╛рдирд╛ рд╣реЛрдЧрд╛ go
, рдФрд░ dispatch
рдлрд┐рд░ рдлрд╝рдВрдХреНрд╢рди рдмрд╕ рд╕рднреА рдереНрд░реЗрдбреНрд╕ рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░реЗрдЧрд╛редрд▓реЗрдХрд┐рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЕрдВрддрд░ рдореМрд▓рд┐рдХ рд╣реИ: рдкрд░рд┐рдгрд╛рдореА рдХреЛрдб рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдиреЗрдЯрд╡рд░реНрдХ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдпрд╣ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдХреБрд╢рд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИред рджрд░рдЕрд╕рд▓, рдЗрд╕ рдкрд░ рд╣рдорд╛рд░рд╛ рд▓рдХреНрд╖реНрдп рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдФрд░ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдХрд╛ рд╕рд╣рдЬреАрд╡рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрдирд╕реЗ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛, рдЕрд░реНрдерд╛рддреНред рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдФрд░ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдкреНрд░рджрд░реНрд╢рди рдХреА рд╕рд╛рджрдЧреАредрд╕реБрдзрд╛рд░
рдореИрдВ рд╕реЙрдХреЗрдЯ рдЧреЛрдж рд▓реЗрдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕реБрдзрд╛рд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛ред рдЕрдХреНрд╕рд░, рд╕реНрд╡реАрдХреГрддрд┐ рдХреЗ рдмрд╛рдж, рдирд┐рд╖реНрдкрд╛рджрди рдХреА рдПрдХ рд╢рд╛рдЦрд╛ рд╣реЛрддреА рд╣реИ: рдЬреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рд╡рд╣ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦреЗрдЧрд╛, рдФрд░ рдирдП рд╕реЙрдХреЗрдЯ рдХреЛ рдПрдХ рдЕрд▓рдЧ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдВрджрд░реНрдн рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рдПрдХ рдирдИ рд╡рд┐рдзрд┐ рдмрдирд╛рдПрдВ goAccept
: async::IoHandler onCompleteGoHandler(coro::Coro* coro, Handler handler) { return [coro, handler](const Error& error) { if (!error) go(std::move(handler)); onComplete(coro, error); }; } struct Acceptor { typedef std::function<void(Socket&)> Handler;
рдФрд░ рдлрд┐рд░ рд╣рдорд╛рд░рд╛ рд╕рд░реНрд╡рд░ рдлреЙрд░реНрдо рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦреЗрдЧрд╛: Acceptor acceptor(8800); LOG("accepting"); go([&acceptor] { while (true) { acceptor.goAccept([](Socket& socket) { try { Buffer buffer; while (true) { buffer.resize(4000); socket.readUntil(buffer, HTTP_DELIM_BODY); socket.write(httpContent("<h1>Hello synca!</h1>")); } } catch (std::exception& e) { LOG("error: " << e.what()); } }); } }); dispatch();
рдЬрд┐рд╕реЗ рд╕рдордЭрдирд╛ рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИредрдкреНрд░рд╢реНрди 1. рдФрд░ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╡рд┐рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рд╕рдВрджрд░реНрднреЛрдВ рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдмрдирд╛рдиреЗ / рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдУрд╡рд░рд╣реЗрдб рд╣реИредрд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдореИрдВ рдЕрдзрд┐рдХрддрдо рднрд╛рд░ рдХреА рдЬрд╛рдБрдЪ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдлрд┐рд░ рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдПрдХ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рдмрдЬрд╛рдП рдПрдХ (!!!) рдзрд╛рдЧрд╛, рдПрдХ рдЧрд┐рдЧрд╛рдмрд┐рдЯ рдиреЗрдЯрд╡рд░реНрдХ рдореЗрдВ рднреАред рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛:- рд╕рд░реНрд╡рд░ 30K RPS рдХреЗ рдирд┐рд░рдВрддрд░ рд▓реЛрдб рдХреЗ рддрд╣рдд рдЪрд▓рддрд╛ рд╣реИ (рдпрд╛рдиреА рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб 30 рд╣рдЬрд╛рд░ рдЕрдиреБрд░реЛрдз)ред
- рд╣рдо
async
рдФрд░ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдкреНрд░реЛрд╕реЗрд╕рд░ рд▓реЛрдб рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ synca
ред
рдкрд░рд┐рдгрд╛рдо рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рджрд┐рдЦрд╛рдП рдЧрдП рд╣реИрдВ:рд╡рд┐рдзрд┐ | рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ | рдзрд╛рдЧреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ | рд╕реАрдкреАрдпреВ рдХреЛрд░ рд▓реЛрдб |
---|
async | 30000 | 1 | 75 ┬▒ 5% |
synca | 30000 | 1 | 80 ┬▒ 5% |
рдореИрдВ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдкреНрд░рд╛рдкреНрдд рдореВрд▓реНрдпреЛрдВ рдореЗрдВ рддреНрд░реБрдЯрд┐ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдХреЗ рджреМрд░рд╛рди рдореВрд▓реНрдпреЛрдВ рдореЗрдВ рдЙрддрд╛рд░-рдЪрдврд╝рд╛рд╡ рд╕реЗ рдЬреБрдбрд╝реА рд╣реИред рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рдпрд╣ рдЕрд╕рдорд╛рди рдЪреИрдирд▓ рд▓реЛрдб рдФрд░ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдХрд╛рд░рдг рд╣реИредрдлрд┐рд░ рднреА, рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рд╕рдВрджрд░реНрднреЛрдВ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реНрд╡рд┐рдЪрд┐рдВрдЧ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рд░рд┐рдЯрд░реНрди рдХреЛрдб рдХреЗ рдмрдЬрд╛рдп рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдлреЗрдВрдХрдиреЗ (рдПрдХ рдЕрдкрд╡рд╛рдж рдЙрддреНрдкрдиреНрди рд╣реЛрдиреЗ рдкрд░ рд╣рд░ рдмрд╛рд░ рд╕реЙрдХреЗрдЯ рдмрдВрдж рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╛рдиреА рд╣рд░ рдмрд╛рд░ рдПрдХ рдирдпрд╛ рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рдУрд╡рд░рд╣реЗрдб рдирдЧрдгреНрдп рд╣реИред рдФрд░ рдпрджрд┐ рдЖрдк рдЙрд╕ рдХреЛрдб рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдЬреЛ рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ HTTP рд╕рдВрджреЗрд╢ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддрд╛ рд╣реИ, рд╕рд╛рде рд╣реА рд╡рд╣ рдХреЛрдб рдЬреЛ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдХрдо рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХреБрдЫ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдФрд░ рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЖрдк рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдХреЛрдИ рдЕрдВрддрд░ рдирд╣реАрдВ рд╣реЛрдЧрд╛ редрдкреНрд░рд╢реНрди 2. рдЕрдЪреНрдЫрд╛, рдЪрд▓рд┐рдП рдмрддрд╛рддреЗ рд╣реИрдВред рдХреНрдпрд╛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╣рд▓ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ?
рдкреНрд░рдореЗрдпред рдХрд┐рд╕реА рднреА рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХрд╛рд░реНрдп рдХреЛ рдХреЛрд░рдЯрд╛рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╕рдмреВрддредрд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓реЗрдВ рдЬреЛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдХрд┐рд╕реА рднреА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ coroutine рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдлрдВрдХреНрд╢рди рдХреЛрд░рдЯрд╛рдЗрди рдХрд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓рд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрд╛рдж, рдЗрд╕ рддрд░рд╣ рдХреЗ рд░реВрдкрд╛рдВрддрд░рд┐рдд рдХреЙрд░рдЯреАрди рдореЗрдВ рдХреБрдЫ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдХреЙрд▓ рдХрд░реЗрдВред рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдХреЙрд▓ рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдЬрдм рдХреЙрд▓ рдХреЗ рдмрд╛рдж рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреЛрдб рдирд╣реАрдВ рд╣реИ:
рдПрдХ рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдРрд╕рд╛ рдХреЛрдб рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ:
рдпрд╛рдиреА
рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ, synca
рд╣рдо рд╕рдВрдмрдВрдзрд┐рдд рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ async
, рдЬреЛ рдСрдкрд░реЗрд╢рди рдкреВрд░рд╛ рд╣реЛрдиреЗ рдкрд░ рдХреЙрд░рдЯреАрди рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рд╣реИрдВрдбрд▓рд░ handler()
рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ ред рдкрд░рд┐рдгрд╛рдо рдареАрдХ рд╡реИрд╕рд╛ рд╣реА рд╣реИредрдЬрдм рд╣рдо рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЙрд▓ рдХреЗ рдмрд╛рдж рдХреЛрдб рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдПрдХ рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдорд▓реЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдРрд╕рд╛ рдХреЛрдб рдЗрд╕рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ:
рдЗрд╕ рддрдереНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрдм рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдХреЛрдИ рдХреЛрдб рдирд╣реАрдВ async
рд╣реИ go
, рд╣рдореЗрдВ рдпрд╣ рдорд┐рд▓рддрд╛ рд╣реИ:
рдпрд╛рдиреА
рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЙрд▓ рдХрдо рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛, рд╣рдо рд╕рднреА рдХреЛрдб рдХреЛ рдХреЛрд░рдЖрдЙрдЯ рдкрд░ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВред QEDрдирд┐рд╖реНрдХрд░реНрд╖
рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рддреЗрдЬреА рд╕реЗ рдЬреИрдХ рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдЬреАрд╡рди рдореЗрдВ рдЯреВрдЯ рд░рд╣рд╛ рд╣реИред рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╕рдордп рдЬреЛ рдХрдард┐рдирд╛рдЗрдпрд╛рдБ рдЖрддреА рд╣реИрдВ, рд╡реЗ рд╕рдмрд╕реЗ рдкреНрд░рдмрд▓ рдФрд░ рдЕрдиреБрднрд╡реА рд╡рд┐рд╢реЗрд╖рдЬреНрдЮреЛрдВ рдХреЛ рднреА рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░ рд╕рдХрддреА рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЖрдкрдХреЛ рдЕрдЪреНрдЫреЗ рдкреБрд░рд╛рдиреЗ рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рдЫреВрдЯ рдирд╣реАрдВ рджреЗрдиреА рдЪрд╛рд╣рд┐рдП: рдХреБрд╢рд▓ рд╣рд╛рдереЛрдВ рдореЗрдВ, рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдХреЛрд░рдЖрдЙрдЯ рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИредрдЕрдЧрд▓реЗ рд▓реЗрдЦ рдореЗрдВ рдПрдХ рдФрд░ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬреЛ рдХреЛрд░рдЯрд╛рдЗрди рдХреА рд╕рднреА рд╢рдХреНрддрд┐ рдФрд░ рдХреНрд╖рдорддрд╛ рдХреЛ рдкреНрд░рдХрдЯ рдХрд░реЗрдЧрд╛!рдЖрдкрдХреЛ рдлрд┐рд░ рд╕реЗ рд╣рд╡рд╛ рдореЗрдВ рдорд┐рд▓рддреЗ рд╣реИрдВ!PS рд╕рднреА рдХреЛрдб рдпрд╣рд╛рдВ рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ : рдмрд┐рдЯрдмрдХреЗрдЯ: рдЧреНрд░рд┐рдбрдо / рд╕рд┐рдирдХрд╛