рдлреБрд▓ I / O рдиреЗрдХреЗрдб рд╕реА рд░рд┐рдПрдХреНрдЯрд░


рдкрд░рд┐рдЪрдп


I / O рд░рд┐рдПрдХреНрдЯрд░ (рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рдЗрд╡реЗрдВрдЯ рд▓реВрдк ) рдЕрддреНрдпрдзрд┐рдХ рд▓реЛрдб рдХрд┐рдП рдЧрдП рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреИрдЯрд░реНрди рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрдИ рд▓реЛрдХрдкреНрд░рд┐рдп рд╕рдорд╛рдзрд╛рдиреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:



рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо I / O рд░рд┐рдПрдХреНрдЯрд░ рдХреЗ рдЗрдиреНрд╕ рдФрд░ рдмрд╣рд┐рд╖реНрдХрд╛рд░ рдФрд░ рдЗрд╕рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ, рдХреЛрдб рдХреА 200 рд╕реЗ рдХрдо рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд▓рд┐рдЦреЗрдВ рдФрд░ рдПрдХ рд╕рд╛рдзрд╛рд░рдг HTTP рд╕рд░реНрд╡рд░ рдХреЛ 40 рдорд┐рд▓рд┐рдпрди рд╕реЗ рдЕрдзрд┐рдХ рдЕрдиреБрд░реЛрдзреЛрдВ / рдорд┐рдирдЯ рдкрд░ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдХрд░реЗрдВред


рдкреНрд░рд╕реНрддрд╛рд╡рдирд╛


  • рд▓реЗрдЦ I / O рд░рд┐рдПрдХреНрдЯрд░ рдХреЗ рдХрд╛рдордХрд╛рдЬ рдХреЛ рд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдХрд░рдиреЗ рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдЬреЛрдЦрд┐рдореЛрдВ рдХрд╛ рдПрд╣рд╕рд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред
  • рд▓реЗрдЦ рдореЗрдВ рдорд╣рд╛рд░рдд рд╣рд╛рд╕рд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕реА рднрд╛рд╖рд╛ рдХреА рдореВрд▓ рдмрд╛рддреЛрдВ рдХрд╛ рдЬреНрдЮрд╛рди рдФрд░ рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЕрдиреБрднрд╡ рдЖрд╡рд╢реНрдпрдХ рд╣реИред
  • рд╕рднреА рдХреЛрдб рд╕реА рдореЗрдВ рд╕рдЦреНрддреА рд╕реЗ ( рд╕рд╛рд╡рдзрд╛рдиреА рд╕реЗ: рд▓рдВрдмреЗ рдкреАрдбреАрдПрдл ) рд▓рд┐рдирдХреНрд╕ рдХреЗ рд▓рд┐рдП C11 рдорд╛рдирдХ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВ рдФрд░ GitHub рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИ ред

рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ?


рдЗрдВрдЯрд░рдиреЗрдЯ рдХреА рдмрдврд╝рддреА рд▓реЛрдХрдкреНрд░рд┐рдпрддрд╛ рдХреЗ рд╕рд╛рде, рд╡реЗрдм рд╕рд░реНрд╡рд░ рдХреЛ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдХрдиреЗрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдФрд░ рдЗрд╕рд▓рд┐рдП рджреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рдЧрдИ рдереА: рдПрдХ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдУрдПрд╕ рдереНрд░реЗрдбреНрд╕ рдкрд░ рдЕрд╡рд░реБрджреНрдз I / O рдФрд░ рдПрдХ рдЗрд╡реЗрдВрдЯ рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдореЗрдВ рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз I / O, рдЬрд┐рд╕реЗ "рд╕рд┐рд╕реНрдЯрдо" рднреА рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЪрдпрдирдХрд░реНрддрд╛ "( epoll / kqueue / IOCP / etc)ред


рдкреНрд░рддреНрдпреЗрдХ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдУрдПрд╕ рдереНрд░реЗрдб рдмрдирд╛рдиреЗ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдкрд╣рд▓рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдгред рдЗрд╕рдХрд╛ рдиреБрдХрд╕рд╛рди рдЦрд░рд╛рдм рд╕реНрдХреЗрд▓реЗрдмрд┐рд▓рд┐рдЯреА рд╣реИ: рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдХрдИ рд╕рдВрджрд░реНрдн рдкрд░рд┐рд╡рд░реНрддрди рдФрд░ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ ред рд╡реЗ рдорд╣рдВрдЧреЗ рдСрдкрд░реЗрд╢рди рд╣реИрдВ рдФрд░ рдХрдиреЗрдХреНрд╢рди рдХреА рдкреНрд░рднрд╛рд╡рд╢рд╛рд▓реА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдореБрдлреНрдд рд░реИрдо рдХреА рдХрдореА рд╣реЛ рд╕рдХрддреА рд╣реИред


рд╕рдВрд╢реЛрдзрд┐рдд рд╕рдВрд╕реНрдХрд░рдг рдереНрд░реЗрдбреНрд╕ (рдереНрд░реЗрдб рдкреВрд▓) рдХреА рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддрд╛ рд╣реИ , рдЬрд┐рд╕рд╕реЗ рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдЕрд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рд░реЛрдХрдирд╛ рдмрдВрдж рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд╛рде рд╣реА рд╕рд╛рде рдПрдХ рдирдИ рд╕рдорд╕реНрдпрд╛ рднреА рдкреЗрд╢ рдХрд░рддрд╛ рд╣реИ: рдпрджрд┐ рджрд┐рдП рдЧрдП рд╕рдордп рдкрд░ рдереНрд░реЗрдб рдкреВрд▓ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдкрдврд╝рдиреЗ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рд╕реЗ рдЕрд╡рд░реБрджреНрдз рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЕрдиреНрдп рдкреЙрдХреЗрдЯ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдЧрд╛ред


рджреВрд╕рд░рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЗрд╡реЗрдВрдЯ рд╕реВрдЪрдирд╛ рдкреНрд░рдгрд╛рд▓реА (рд╕рд┐рд╕реНрдЯрдо рдЪрдпрдирдХрд░реНрддрд╛) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдУрдПрд╕ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдпрд╣ рд▓реЗрдЦ рдЖрдИ / рдУ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд▓рд┐рдП рддрддреНрдкрд░рддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрд▓рд░реНрдЯ (рдШрдЯрдирд╛рдУрдВ, рд╕реВрдЪрдирд╛рдУрдВ) рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕рдмрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд┐рд╕реНрдЯрдо рдЪрдпрдирдХрд░реНрддрд╛ рдХреА рдЪрд░реНрдЪрд╛ рдХрд░рддрд╛ рд╣реИ, рдмрдЬрд╛рдп рдЙрдирдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрд▓рд░реНрдЯ рдХреЗ ред рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдХрд╛ рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝реНрд▓реЛрдЪрд╛рд░реНрдЯ рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:



рдЗрди рддрд░реАрдХреЛрдВ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:


  • I / O рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд░рдирд╛ рддрдм рддрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдЯреНрд░реАрдо рдХреЛ рдирд┐рд▓рдВрдмрд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрдм рддрдХ OS рдЖрдиреЗ рд╡рд╛рд▓реА IP рдкреИрдХреЗрдЯ рдХреЛ рдмрд╛рдЗрдЯ рд╕реНрдЯреНрд░реАрдо ( TCP , рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛) рдореЗрдВ рдареАрдХ рд╕реЗ рдбреАрдлрд╝реНрд░реЗрдЧреНрдореЗрдВрдЯ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдпрд╛ рдПрдирдЖрдИрд╕реА (рдбреЗрдЯрд╛ рднреЗрдЬрдирд╛) рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрдВрддрд░рд┐рдХ рд░рд╛рдЗрдЯ рдмрдлрд╝рд░реНрд╕ рдореЗрдВ рдкрд░реНрдпрд╛рдкреНрдд рд╕реНрдерд╛рди рдЦрд╛рд▓реА рдХрд░ рджреЗрддрд╛ рд╣реИред
  • рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж, рд╕рд┐рд╕реНрдЯрдо рдЪрдпрдирдХрд░реНрддрд╛ рдЙрд╕ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдУрдПрд╕ рдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЖрдИрдкреА тАЛтАЛрдкреИрдХреЗрдЯ (рдЯреАрд╕реАрдкреА, рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛) рдХреЛ рдбреАрдлрд╝реНрд░реИрдЧреНрдореЗрдиреНрдЯ рдХрд░ рджрд┐рдпрд╛ рд╣реИ рдпрд╛ рдЖрдВрддрд░рд┐рдХ рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдмрдлрд╝рд░реНрд╕ рдореЗрдВ рдкрд░реНрдпрд╛рдкреНрдд рдЬрдЧрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрдкрд▓рдмреНрдз рд╣реИ (рдбреЗрдЯрд╛ рднреЗрдЬ рд░рд╣рд╛ рд╣реИ)ред

рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ I / O рдХреЗ рд▓рд┐рдП OS рдереНрд░реЗрдб рдХреЛ рдЬрдорд╛ рдХрд░рдирд╛ рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рд╢рдХреНрддрд┐ рдХреА рдмрд░реНрдмрд╛рджреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдереНрд░реЗрдбреНрд╕ рдЙрдкрдпреЛрдЧреА рдХрд╛рд░реНрдп рдХреЗ рд╕рд╛рде рд╡реНрдпрд╕реНрдд рдирд╣реАрдВ рд╣реИрдВ (рд╢рдмреНрдж "рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рд░реБрдХрд╛рд╡рдЯ" рдореЗрдВ рдЗрд╕рдХреА рдЬрдбрд╝реЗрдВ рд╣реИрдВ )ред рд╕рд┐рд╕реНрдЯрдо рдЪрдпрдирдХрд░реНрддрд╛ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рд╕реАрдкреАрдпреВ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдЕрдзрд┐рдХ рдЖрд░реНрдерд┐рдХ рд░реВрдк рд╕реЗ рдЙрдкрднреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред


рд░рд┐рдПрдХреНрдЯрд░ I / O рдореЙрдбрд▓


I / O рд░рд┐рдПрдХреНрдЯрд░ рд╕рд┐рд╕реНрдЯрдо рдЪрдпрдирдХрд░реНрддрд╛ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛрдб рдХреЗ рдмреАрдЪ рдПрдХ рдкрд░рдд рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рд╕рд┐рджреНрдзрд╛рдВрдд рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлреНрд▓реЛрдЪрд╛рд░реНрдЯ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рд╣реИ:



  • рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛рддрд╛ рд╣реВрдВ рдХрд┐ рдПрдХ рдШрдЯрдирд╛ рдПрдХ рдЕрдзрд┐рд╕реВрдЪрдирд╛ рд╣реИ рдХрд┐ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реЙрдХреЗрдЯ рдПрдХ рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз I / O рдСрдкрд░реЗрд╢рди рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИред
  • рдПрдХ рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬрд┐рд╕реЗ I / O рд░рд┐рдПрдХреНрдЯрд░ рджреНрд╡рд╛рд░рд╛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдХреЛрдИ рдИрд╡реЗрдВрдЯ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рддрдм рдПрдХ рдиреЙрди-рдмреНрд▓реЙрдХрд┐рдВрдЧ I / O рдСрдкрд░реЗрд╢рди рдХрд░рддрд╛ рд╣реИред

рдпрд╣ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ I / O рд░рд┐рдПрдХреНрдЯрд░ рдкрд░рд┐рднрд╛рд╖рд╛ рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рд╣реИ, рд▓реЗрдХрд┐рди 1 рд╕реНрдЯреНрд░реАрдо: 1 рд░рд┐рдПрдХреНрдЯрд░ рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдЕрд╡рдзрд╛рд░рдгрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдХреБрдЫ рднреА рдирд╣реАрдВ рд░реЛрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рд╕рднреА рд╕реАрдкреАрдпреВ рдХреЛрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реЛрддрд╛ рд╣реИред


рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди


рд╣рдордиреЗ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ reactor.h рдлрд╝рд╛рдЗрд▓, рдФрд░ reactor.c рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ reactor.c ред reactor.h рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдШреЛрд╖рдгрд╛рдПрдБ рд╢рд╛рдорд┐рд▓ рд╣реЛрдВрдЧреА:


рд░рд┐рдПрдХреНрдЯрд░ рдореЗрдВ рд╡рд┐рдЬреНрдЮрд╛рдкрди рджрд┐рдЦрд╛рдПрдВ
 typedef struct reactor Reactor; /* *   ,    I/O    *    . */ typedef void (*Callback)(void *arg, int fd, uint32_t events); /* *  `NULL`   , -`NULL`   `Reactor`  *  . */ Reactor *reactor_new(void); /* *   ,       *    I/O . * *    -1   , 0   . */ int reactor_destroy(Reactor *reactor); int reactor_register(const Reactor *reactor, int fd, uint32_t interest, Callback callback, void *callback_arg); int reactor_deregister(const Reactor *reactor, int fd); int reactor_reregister(const Reactor *reactor, int fd, uint32_t interest, Callback callback, void *callback_arg); /* *     - `timeout`. * *           * /    . */ int reactor_run(const Reactor *reactor, time_t timeout); 

рд░рд┐рдПрдХреНрдЯрд░ рдХреА I / O рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдПрдХ рдПрдкреЛрд▓ рдЪрдпрдирдХрд░реНрддрд╛ рдлрд╝рд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдФрд░ рдПрдХ GHashTable рд╣реИрд╢ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ , рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рд╕реЙрдХреЗрдЯ рдореИрдкреНрд╕ GHashTable (рдПрдХ рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рд╕реЗ рдПрдХ рд╕рдВрд░рдЪрдирд╛ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рддрд░реНрдХ) рдХреЗ рд╣реЛрддреЗ рд╣реИрдВред


рд░рд┐рдПрдХреНрдЯрд░ рдФрд░ рдХреЙрд▓рдмреИрдХрдбреЗрдЯрд╛ рджрд┐рдЦрд╛рдПрдВ
 struct reactor { int epoll_fd; GHashTable *table; // (int, CallbackData) }; typedef struct { Callback callback; void *arg; } CallbackData; 

рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╣рдордиреЗ рд╕реВрдЪрдХ рджреНрд╡рд╛рд░рд╛ рдЕрдкреВрд░реНрдг рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИред reactor.h рд╣рдо reactor рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ reactor.c рдЗрд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЕрдкрдиреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдмрджрд▓рдиреЗ рд╕реЗ рд░реЛрдХрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдбреЗрдЯрд╛ рдЫрд┐рдкрд╛рдиреЗ рдХреЗ рдкреИрдЯрд░реНрди рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ рдЬреЛ рд╕реА рдХреЗ рд╢рдмреНрджрд╛рд░реНрде рдореЗрдВ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рд░реВрдк рд╕реЗ рдлрд┐рдЯ рдмреИрдарддрд╛ рд╣реИред


reactor_register , reactor_deregister рдФрд░ reactor_reregister , рд╕рд┐рд╕реНрдЯрдо рд╕рд┐рд▓реЗрдХреНрдЯрд░ рдФрд░ рд╣реИрд╢ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдШрдЯрдирд╛ рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рдХреЗ рд╕реЙрдХреЗрдЯреНрд╕ рдХреА рд╕реВрдЪреА рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╣реИрдВред


рдкрдВрдЬреАрдХрд░рдг рд╕реБрд╡рд┐рдзрд╛рдПрдБ рджрд┐рдЦрд╛рдПрдВ
 #define REACTOR_CTL(reactor, op, fd, interest) \ if (epoll_ctl(reactor->epoll_fd, op, fd, \ &(struct epoll_event){.events = interest, \ .data = {.fd = fd}}) == -1) { \ perror("epoll_ctl"); \ return -1; \ } int reactor_register(const Reactor *reactor, int fd, uint32_t interest, Callback callback, void *callback_arg) { REACTOR_CTL(reactor, EPOLL_CTL_ADD, fd, interest) g_hash_table_insert(reactor->table, int_in_heap(fd), callback_data_new(callback, callback_arg)); return 0; } int reactor_deregister(const Reactor *reactor, int fd) { REACTOR_CTL(reactor, EPOLL_CTL_DEL, fd, 0) g_hash_table_remove(reactor->table, &fd); return 0; } int reactor_reregister(const Reactor *reactor, int fd, uint32_t interest, Callback callback, void *callback_arg) { REACTOR_CTL(reactor, EPOLL_CTL_MOD, fd, interest) g_hash_table_insert(reactor->table, int_in_heap(fd), callback_data_new(callback, callback_arg)); return 0; } 

I / O рд░рд┐рдПрдХреНрдЯрд░ fd рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХреЗ рд╕рд╛рде рдИрд╡реЗрдВрдЯ рдХреЛ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЗрд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХрд╣рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдпрд╣ fd рдкрд╛рд╕ рдХрд░рддрд╛ рд╣реИ, рдЬреЗрдирд░реЗрдЯ рдХреА рдЧрдИ рдШрдЯрдирд╛рдУрдВ рдХрд╛ рдмрд┐рдЯ рдорд╛рд╕реНрдХ рдФрд░ void рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпреВрдЬрд░ рдкреЙрдЗрдВрдЯрд░ред


рджрд┐рдЦрд╛рдПрдБ рд░рд┐рдПрдХреНрдЯрд░_рд░реБрди () рдлрд╝рдВрдХреНрд╢рди
 int reactor_run(const Reactor *reactor, time_t timeout) { int result; struct epoll_event *events; if ((events = calloc(MAX_EVENTS, sizeof(*events))) == NULL) abort(); time_t start = time(NULL); while (true) { time_t passed = time(NULL) - start; int nfds = epoll_wait(reactor->epoll_fd, events, MAX_EVENTS, timeout - passed); switch (nfds) { //  case -1: perror("epoll_wait"); result = -1; goto cleanup; //   case 0: result = 0; goto cleanup; //   default: //    for (int i = 0; i < nfds; i++) { int fd = events[i].data.fd; CallbackData *callback = g_hash_table_lookup(reactor->table, &fd); callback->callback(callback->arg, fd, events[i].events); } } } cleanup: free(events); return result; } 

рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛрдб рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХреА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд░реВрдк рд▓реЗрдЧреА:



рд╕рд┐рдВрдЧрд▓ рдереНрд░реЗрдбреЗрдб рд╕рд░реНрд╡рд░


рдЙрдЪреНрдЪ рднрд╛рд░ рдХреЗ рддрд╣рдд I / O рд░рд┐рдПрдХреНрдЯрд░ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдЫрд╡рд┐ рдХреЗ рд╕рд╛рде рдХрд┐рд╕реА рднреА рдЕрдиреБрд░реЛрдз рдХрд╛ рдЬрд╡рд╛рдм рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓ HTTP рд╡реЗрдм рд╕рд░реНрд╡рд░ рд▓рд┐рдЦреЗрдВрдЧреЗред


HTTP рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рддреНрд╡рд░рд┐рдд рд╕рдВрджрд░реНрдн

HTTP рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди-рд╕реНрддрд░ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╣реИ рдЬреЛ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рд╕рд╛рде рд╕рд░реНрд╡рд░ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


HTTP рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдЯреАрд╕реАрдкреА рдкрд░рд┐рд╡рд╣рди рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдкреНрд░рд╛рд░реВрдк рдХреЗ рд╕рдВрджреЗрд╢ рднреЗрдЬрдирд╛ рдФрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ред


рдЕрдиреБрд░реЛрдз рдкреНрд░рд╛рд░реВрдк


 <> <URI> < HTTP>CRLF < 1>CRLF < 2>CRLF < N>CRLF CRLF <> 

  • CRLF рджреЛ рд╡рд░реНрдгреЛрдВ рдХрд╛ рдПрдХ рдХреНрд░рдо рд╣реИ: \r рдФрд░ \n , рдХреНрд╡реЗрд░реА, рд╣реЗрдбрд░ рдФрд░ рдбреЗрдЯрд╛ рдХреА рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐ рдХреЛ рдЕрд▓рдЧ рдХрд░рддрд╛ рд╣реИред
  • <> CONNECT , DELETE , GET , HEAD , OPTIONS , PATCH , POST , PUT , TRACE ред рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╣рдорд╛рд░реЗ рд╕рд░реНрд╡рд░ рдкрд░ рдПрдХ GET рдХрдорд╛рдВрдб рднреЗрдЬреЗрдЧрд╛, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ "рдореБрдЭреЗ рдлрд╝рд╛рдЗрд▓ рдХреА рд╕рд╛рдордЧреНрд░реА рднреЗрдЬреЗрдВред"
  • <URI> рдПрдХреАрдХреГрдд рд╕рдВрд╕рд╛рдзрди рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИ ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ URI = /index.html , рддреЛ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдЯ рдХреЗ рдореБрдЦреНрдп рдкреГрд╖реНрда рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИред
  • < HTTP> - HTTP/XY рдкреНрд░рд╛рд░реВрдк рдореЗрдВ HTTP/XY рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╕рдВрд╕реНрдХрд░рдгред рдЕрдм рддрдХ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг HTTP/1.1 ред
  • < N> рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдПрдХ рдкреНрд░рдореБрдЦ-рдореВрд▓реНрдп рд╡рд╛рд▓рд╛ рдЬреЛрдбрд╝рд╛ рд╣реИ <>: <> , рдЬреЛ рдЖрдЧреЗ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡рд░ рдХреЛ рднреЗрдЬрд╛ рдЧрдпрд╛ рд╣реИред
  • <> - рдСрдкрд░реЗрд╢рди рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡рд░ рджреНрд╡рд╛рд░рд╛ рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ред рдЕрдХреНрд╕рд░ рдпрд╣ рд╕рд┐рд░реНрдл JSON рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред

рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕реНрд╡рд░реВрдк


 < HTTP> < > < >CRLF < 1>CRLF < 2>CRLF < N>CRLF CRLF <> 

  • < > рдПрдХ рдСрдкрд░реЗрд╢рди рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдПрдХ рд╕рдВрдЦреНрдпрд╛ рд╣реИред рд╣рдорд╛рд░рд╛ рд╕рд░реНрд╡рд░ рд╣рдореЗрд╢рд╛ рд╕реНрдерд┐рддрд┐ 200 (рд╕рдлрд▓ рд╕рдВрдЪрд╛рд▓рди) рд▓реМрдЯрд╛рдПрдЧрд╛ред
  • < > - рд╕реНрдерд┐рддрд┐ рдХреЛрдб рдХрд╛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ред рд╕реНрдерд┐рддрд┐ рдХреЛрдб 200 рдХреЗ рд▓рд┐рдП, рдпрд╣ OK ред
  • < N> - рдЕрдиреБрд░реЛрдз рдореЗрдВ рдЙрд╕реА рдкреНрд░рд╛рд░реВрдк рдХрд╛ рд╢реАрд░реНрд╖рд▓реЗрдЦред рд╣рдо Content-Length (рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЖрдХрд╛рд░) рдФрд░ Content-Type: text/html (рд╡рд╛рдкрд╕реА рдкреНрд░рдХрд╛рд░ рдбреЗрдЯрд╛) рд╢реАрд░реНрд╖ Content-Type: text/html рд▓реМрдЯрд╛рдПрдВрдЧреЗред
  • <> - рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдЕрдиреБрд░реЛрдзрд┐рдд рдбреЗрдЯрд╛ред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ HTML рдореЗрдВ рдЫрд╡рд┐ рдХрд╛ рдорд╛рд░реНрдЧ рд╣реИред

http_server.c (рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рд╕рд░реНрд╡рд░) рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдПрдХ common.h рдлрд╝рд╛рдЗрд▓ рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдирд┐рдореНрди рдлрд╝рдВрдХреНрд╢рди рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:


рдлрдВрдХреНрд╢рди рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдореЗрдВ рджрд┐рдЦрд╛рдПрдБ
 /* *  ,    ,    *    . */ static void on_accept(void *arg, int fd, uint32_t events); /* *  ,    ,    *   HTTP . */ static void on_send(void *arg, int fd, uint32_t events); /* *  ,    ,    *    HTTP . */ static void on_recv(void *arg, int fd, uint32_t events); /* *      . */ static void set_nonblocking(int fd); /* *     stderr      *  `EXIT_FAILURE`. */ static noreturn void fail(const char *format, ...); /* *    ,    * TCP . */ static int new_server(bool reuse_port); 

рдлрд╝рдВрдХреНрд╢рди рдореИрдХреНрд░реЛ SAFE_CALL() рднреА рд╡рд░реНрдгрд┐рдд рд╣реИ рдФрд░ fail() рдлрд╝рдВрдХреНрд╢рди рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИред рдореИрдХреНрд░реЛ рддреНрд░реБрдЯрд┐ рдХреЗ рд╕рд╛рде рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдореВрд▓реНрдп рдХреА рддреБрд▓рдирд╛ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рд╢рд░реНрдд рдкреВрд░реА рд╣реЛ рдЬрд╛рддреА рд╣реИ, рддреЛ рдпрд╣ fail() рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ:


 #define SAFE_CALL(call, error) \ do { \ if ((call) == error) { \ fail("%s", #call); \ } \ } while (false) 

fail() рдлрдВрдХреНрд╢рди, рдкрд╛рд╕ рдХрд┐рдП рдЧрдП рддрд░реНрдХреЛрдВ рдХреЛ рдЯрд░реНрдорд┐рдирд▓ (рдЬреИрд╕реЗ EXIT_FAILURE fail() рдкреНрд░рд┐рдВрдЯ рдХрд░рддрд╛ рд╣реИ рдФрд░ EXIT_FAILURE рдХреЛрдб рдХреЗ рд╕рд╛рде рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ:


 static noreturn void fail(const char *format, ...) { va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); fprintf(stderr, ": %s\n", strerror(errno)); exit(EXIT_FAILURE); } 

new_server() рдлрд╝рдВрдХреНрд╢рди рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ socket() , bind() рдФрд░ listen() рджреНрд╡рд╛рд░рд╛ рдмрдирд╛рдИ рдЧрдИ "рд╕рд░реНрд╡рд░" рд╕реЙрдХреЗрдЯ рдХреА рдлрд╝рд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ рдФрд░ рдЧреИрд░-рдЕрд╡рд░реЛрдзрдХ рдореЛрдб рдореЗрдВ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдХрдиреЗрдХреНрд╢рди рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИред


рдлрд╝рдВрдХреНрд╢рди рджрд┐рдЦрд╛рдПрдВ new_server ()
 static int new_server(bool reuse_port) { int fd; SAFE_CALL((fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP)), -1); if (reuse_port) { SAFE_CALL( setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &(int){1}, sizeof(int)), -1); } struct sockaddr_in addr = {.sin_family = AF_INET, .sin_port = htons(SERVER_PORT), .sin_addr = {.s_addr = inet_addr(SERVER_IPV4)}, .sin_zero = {0}}; SAFE_CALL(bind(fd, (struct sockaddr *)&addr, sizeof(addr)), -1); SAFE_CALL(listen(fd, SERVER_BACKLOG), -1); return fd; } 

  • рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╕реЙрдХреЗрдЯ рд╢реБрд░реВ рдореЗрдВ SOCK_NONBLOCK рдзреНрд╡рдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЧреИрд░-рдЕрд╡рд░реЛрдзрдХ рдореЛрдб рдореЗрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддрд╛рдХрд┐ on_accept() рдлрд╝рдВрдХреНрд╢рди (рдФрд░ рдкрдврд╝реЗрдВ) рдореЗрдВ, accept() рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рд╕реНрдЯреНрд░реАрдо рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рд░реЛрдХ рди рд╕рдХреЗред
  • рдпрджрд┐ reuse_port true , рддреЛ рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рд╕реЙрдХреЗрдЯ рдХреЛ рдПрдХ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рд╕рдорд╛рди рдкреЛрд░реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП setsockopt() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ SO_REUSEPORT рд╡рд┐рдХрд▓реНрдк рдХреЗ рд╕рд╛рде рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдЧрд╛ (рдЕрдиреБрднрд╛рдЧ "рдорд▓реНрдЯреА-рдереНрд░реЗрдбреЗрдб рд╕рд░реНрд╡рд░" рджреЗрдЦреЗрдВ)ред

on_accept() рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЛ рддрдм рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм OS EPOLLIN рдИрд╡реЗрдВрдЯ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЗрд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдПрдХ рдирдпрд╛ рдХрдиреЗрдХреНрд╢рди рд╕реНрд╡реАрдХрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред on_accept() рдПрдХ рдирдП рдХрдиреЗрдХреНрд╢рди рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ рдЧреИрд░-рдЕрд╡рд░реЛрдзрдХ рдореЛрдб рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рддрд╛ рд╣реИ рдФрд░ on_recv() O рд░рд┐рдПрдХреНрдЯрд░ рдореЗрдВ on_recv() рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЗ рд╕рд╛рде рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд░рддрд╛ рд╣реИред


On_accept () рдлрд╝рдВрдХреНрд╢рди рджрд┐рдЦрд╛рдПрдВ
 static void on_accept(void *arg, int fd, uint32_t events) { int incoming_conn; SAFE_CALL((incoming_conn = accept(fd, NULL, NULL)), -1); set_nonblocking(incoming_conn); SAFE_CALL(reactor_register(reactor, incoming_conn, EPOLLIN, on_recv, request_buffer_new()), -1); } 

OS рдХреЛ EPOLLIN рдмрдирд╛рдиреЗ рдХреЗ рдмрд╛рдж on_recv() рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЗрд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ on_accept() рджреНрд╡рд╛рд░рд╛ рдкрдВрдЬреАрдХреГрдд рдХрдиреЗрдХреНрд╢рди рдбреЗрдЯрд╛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИред


on_recv() рдкреВрд░реНрдг HTTP рдЕрдиреБрд░реЛрдз рдкреНрд░рд╛рдкреНрдд рд╣реЛрдиреЗ рддрдХ рдХрдиреЗрдХреНрд╢рди рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝рддрд╛ рд╣реИ, рдлрд┐рд░ рд╡рд╣ HTTP рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП on_send() рд╣реИрдВрдбрд▓рд░ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЧреНрд░рд╛рд╣рдХ рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╕реЙрдХреЗрдЯ рдбреЗрд░реЗрдЧрд┐рд╕реНрдЯреНрд╕ рдФрд░ close() рд╕рд╛рде close() рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред


On_recv () рдлрд╝рдВрдХреНрд╢рди рджрд┐рдЦрд╛рдПрдВ
 static void on_recv(void *arg, int fd, uint32_t events) { RequestBuffer *buffer = arg; //      ,  recv  0   ssize_t nread; while ((nread = recv(fd, buffer->data + buffer->size, REQUEST_BUFFER_CAPACITY - buffer->size, 0)) > 0) buffer->size += nread; //    if (nread == 0) { SAFE_CALL(reactor_deregister(reactor, fd), -1); SAFE_CALL(close(fd), -1); request_buffer_destroy(buffer); return; } // read  ,   ,     //  if (errno != EAGAIN && errno != EWOULDBLOCK) { request_buffer_destroy(buffer); fail("read"); } //   HTTP   .    //     if (request_buffer_is_complete(buffer)) { request_buffer_clear(buffer); SAFE_CALL(reactor_reregister(reactor, fd, EPOLLOUT, on_send, buffer), -1); } } 

on_send() рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрдм рдУрдПрд╕ рдПрдХ EPOLLOUT рдШрдЯрдирд╛ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ on_recv() рджреНрд╡рд╛рд░рд╛ рдкрдВрдЬреАрдХреГрдд рдХрдиреЗрдХреНрд╢рди рдбреЗрдЯрд╛ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИред рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдЫрд╡рд┐ рдХреЗ рд╕рд╛рде рдПрдЪрдЯреАрдПрдордПрд▓ рдпреБрдХреНрдд рдПрдХ HTTP рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рднреЗрдЬрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЛ on_recv() ред


On_send () рдлрд╝рдВрдХреНрд╢рди рджрд┐рдЦрд╛рдПрдВ
 static void on_send(void *arg, int fd, uint32_t events) { const char *content = "<img " "src=\"https://habrastorage.org/webt/oh/wl/23/" "ohwl23va3b-dioerobq_mbx4xaw.jpeg\">"; char response[1024]; sprintf(response, "HTTP/1.1 200 OK" CRLF "Content-Length: %zd" CRLF "Content-Type: " "text/html" DOUBLE_CRLF "%s", strlen(content), content); SAFE_CALL(send(fd, response, strlen(response), 0), -1); SAFE_CALL(reactor_reregister(reactor, fd, EPOLLIN, on_recv, arg), -1); } 

рдФрд░ рдЕрдВрдд рдореЗрдВ, рдлрд╝рд╛рдЗрд▓ рдореЗрдВ http_server.c , main() рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рд╣рдо reactor_new() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ I / O рд░рд┐рдПрдХреНрдЯрд░ рдмрдирд╛рддреЗ рд╣реИрдВ, рдПрдХ рд╕рд░реНрд╡рд░ рд╕реЙрдХреЗрдЯ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдкрдВрдЬреАрдХреГрдд рдХрд░рддреЗ рд╣реИрдВ, рд░рд┐рдПрдХреНрдЯрд░ рдХреЛ reactor_run() рдареАрдХ рдПрдХ рдорд┐рдирдЯ рдХреЗ reactor_run() рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ рдФрд░ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддреЗ рд╣реИрдВ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╕реЗред


Http_server.c рджрд┐рдЦрд╛рдПрдБ
 #include "reactor.h" static Reactor *reactor; #include "common.h" int main(void) { SAFE_CALL((reactor = reactor_new()), NULL); SAFE_CALL( reactor_register(reactor, new_server(false), EPOLLIN, on_accept, NULL), -1); SAFE_CALL(reactor_run(reactor, SERVER_TIMEOUT_MILLIS), -1); SAFE_CALL(reactor_destroy(reactor), -1); } 

рдЬрд╛рдВрдЪреЗрдВ рдХрд┐ рд╕рдм рдХреБрдЫ рдЕрдкреЗрдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд╣рдо рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ (рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд░реВрдЯ рдореЗрдВ chmod a+x compile.sh && ./compile.sh ) рдФрд░ рд╕реНрд╡-рд▓рд┐рдЦрд┐рдд рд╕рд░реНрд╡рд░ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ http://127.0.0.1:18470 рдЦреЛрд▓реЗрдВ рдФрд░ рдЬреЛ рдЕрдкреЗрдХреНрд╖рд┐рдд рдерд╛ рдЙрд╕рдХрд╛ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░реЗрдВ:



рдкреНрд░рджрд░реНрд╢рди рдорд╛рдк


рдореЗрд░реА рдХрд╛рд░ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рджрд┐рдЦрд╛рдПрдВ
 $ screenfetch MMMMMMMMMMMMMMMMMMMMMMMMMmds+. OS: Mint 19.1 tessa MMm----::-://////////////oymNMd+` Kernel: x86_64 Linux 4.15.0-20-generic MMd /++ -sNMd: Uptime: 2h 34m MMNso/` dMM `.::-. .-::.` .hMN: Packages: 2217 ddddMMh dMM :hNMNMNhNMNMNh: `NMm Shell: bash 4.4.20 NMm dMM .NMN/-+MMM+-/NMN` dMM Resolution: 1920x1080 NMm dMM -MMm `MMM dMM. dMM DE: Cinnamon 4.0.10 NMm dMM -MMm `MMM dMM. dMM WM: Muffin NMm dMM .mmd `mmm yMM. dMM WM Theme: Mint-Y-Dark (Mint-Y) NMm dMM` ..` ... ydm. dMM GTK Theme: Mint-Y [GTK2/3] hMM- +MMd/-------...-:sdds dMM Icon Theme: Mint-Y -NMm- :hNMNNNmdddddddddy/` dMM Font: Noto Sans 9 -dMNs-``-::::-------.`` dMM CPU: Intel Core i7-6700 @ 8x 4GHz [52.0┬░C] `/dMNmy+/:-------------:/yMMM GPU: NV136 ./ydNMMMMMMMMMMMMMMMMMMMMM RAM: 2544MiB / 7926MiB \.MMMMMMMMMMMMMMMMMMM 

рд╣рдо рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рд╕рд░реНрд╡рд░ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрддреЗ рд╣реИрдВред рдЖрдЗрдП рджреЛ рдЯрд░реНрдорд┐рдирд▓ рдЦреЛрд▓реЗрдВ: рдПрдХ рдореЗрдВ рд╣рдо рдЪрд▓рд╛рддреЗ рд╣реИрдВ ./http_server , рджреВрд╕рд░реЗ рдореЗрдВ - wrk ред рдПрдХ рдорд┐рдирдЯ рдХреЗ рдмрд╛рдж, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЖрдВрдХрдбрд╝реЗ рджреВрд╕рд░реЗ рдЯрд░реНрдорд┐рдирд▓ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрдВрдЧреЗ:


 $ wrk -c100 -d1m -t8 http://127.0.0.1:18470 -H "Host: 127.0.0.1:18470" -H "Accept-Language: en-US,en;q=0.5" -H "Connection: keep-alive" Running 1m test @ http://127.0.0.1:18470 8 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 493.52us 76.70us 17.31ms 89.57% Req/Sec 24.37k 1.81k 29.34k 68.13% 11657769 requests in 1.00m, 1.60GB read Requests/sec: 193974.70 Transfer/sec: 27.19MB 

рд╣рдорд╛рд░рд╛ рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рд╕рд░реНрд╡рд░ рдкреНрд░рддрд┐ рдорд┐рдирдЯ 11 рдорд┐рд▓рд┐рдпрди рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛, рдЬреЛ 100 рдХрдиреЗрдХреНрд╢рди рд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реБрдЖ рдерд╛ред рдПрдХ рдмреБрд░рд╛ рдкрд░рд┐рдгрд╛рдо рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рдЗрд╕рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ?


рдмрд╣реБрд╕реНрддрд░реАрдп рд╕рд░реНрд╡рд░


рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдПрдХ I / O рд░рд┐рдПрдХреНрдЯрд░ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдзрд╛рд░рд╛рдУрдВ рдореЗрдВ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рд╕рднреА CPU рдХреЛрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЖрдЗрдП рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░реЗрдВ:


Http_server_multithreaded.c рджрд┐рдЦрд╛рдПрдБ
 #include "reactor.h" static Reactor *reactor; #pragma omp threadprivate(reactor) #include "common.h" int main(void) { #pragma omp parallel { SAFE_CALL((reactor = reactor_new()), NULL); SAFE_CALL(reactor_register(reactor, new_server(true), EPOLLIN, on_accept, NULL), -1); SAFE_CALL(reactor_run(reactor, SERVER_TIMEOUT_MILLIS), -1); SAFE_CALL(reactor_destroy(reactor), -1); } } 

рдЕрдм рдкреНрд░рддреНрдпреЗрдХ рдзрд╛рдЧрд╛ рдХрд╛ рдЕрдкрдирд╛ рд░рд┐рдПрдХреНрдЯрд░ рд╣реИ:


 static Reactor *reactor; #pragma omp threadprivate(reactor) 

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ new_server() рдХрд╛ рддрд░реНрдХ true ред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рдо рд╕рд░реНрд╡рд░ рд╕реЙрдХреЗрдЯ рдХреЛ SO_REUSEPORT рд╡рд┐рдХрд▓реНрдк рдореЗрдВ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЖрдк рдпрд╣рд╛рдВ рдФрд░ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред


рджреВрд╕рд░рд╛ рд░рди


рдЕрдм рд╣рдо рдПрдХ рдмрд╣реБрд╕реНрддрд░реАрдп рд╕рд░реНрд╡рд░ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкреЗрдВрдЧреЗ:


 $ wrk -c100 -d1m -t8 http://127.0.0.1:18470 -H "Host: 127.0.0.1:18470" -H "Accept-Language: en-US,en;q=0.5" -H "Connection: keep-alive" Running 1m test @ http://127.0.0.1:18470 8 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.14ms 2.53ms 40.73ms 89.98% Req/Sec 79.98k 18.07k 154.64k 78.65% 38208400 requests in 1.00m, 5.23GB read Requests/sec: 635876.41 Transfer/sec: 89.14MB 

1 рдорд┐рдирдЯ рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ ~ 3.28 рдЧреБрдирд╛ рдмрдврд╝ рдЧрдИ! рд▓реЗрдХрд┐рди рдЧреЛрд▓ рд╕рдВрдЦреНрдпрд╛ рддрдХ, рдХреЗрд╡рд▓ ~ рджреЛ рдорд┐рд▓рд┐рдпрди рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рдерд╛, рдЪрд▓реЛ рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, perf рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рдЖрдБрдХрдбрд╝реЛрдВ рдХреЛ рджреЗрдЦреЗрдВ:


 $ sudo perf stat -B -e task-clock,context-switches,cpu-migrations,page-faults,cycles,instructions,branches,branch-misses,cache-misses ./http_server_multithreaded Performance counter stats for './http_server_multithreaded': 242446,314933 task-clock (msec) # 4,000 CPUs utilized 1 813 074 context-switches # 0,007 M/sec 4 689 cpu-migrations # 0,019 K/sec 254 page-faults # 0,001 K/sec 895 324 830 170 cycles # 3,693 GHz 621 378 066 808 instructions # 0,69 insn per cycle 119 926 709 370 branches # 494,653 M/sec 3 227 095 669 branch-misses # 2,69% of all branches 808 664 cache-misses 60,604330670 seconds time elapsed 

рд╕реАрдкреАрдпреВ рдЖрддреНрдореАрдпрддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ , -march=native , -march=native рд╕рд╛рде рд╕рдВрдХрд▓рд┐рдд рдХрд░рдирд╛, рдХреИрд╢ рдореЗрдВ рд╣рд┐рдЯ рдХреА рд╕рдВрдЦреНрдпрд╛ MAX_EVENTS рдФрд░ EPOLLET рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рд╡реГрджреНрдзрд┐ рдирд╣реАрдВ рд╣реБрдИред рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ рдпрджрд┐ рдЖрдк рдПрдХ рд╕рд╛рде рдХрдиреЗрдХреНрд╢рди рдХреА рд╕рдВрдЦреНрдпрд╛ рдмрдврд╝рд╛рддреЗ рд╣реИрдВ?


352 рдПрдХ рд╕рд╛рде рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдЖрдБрдХрдбрд╝реЗ:


 $ wrk -c352 -d1m -t8 http://127.0.0.1:18470 -H "Host: 127.0.0.1:18470" -H "Accept-Language: en-US,en;q=0.5" -H "Connection: keep-alive" Running 1m test @ http://127.0.0.1:18470 8 threads and 352 connections Thread Stats Avg Stdev Max +/- Stdev Latency 2.12ms 3.79ms 68.23ms 87.49% Req/Sec 83.78k 12.69k 169.81k 83.59% 40006142 requests in 1.00m, 5.48GB read Requests/sec: 665789.26 Transfer/sec: 93.34MB 

рд╡рд╛рдВрдЫрд┐рдд рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрдиреЗрдХреНрд╢рди рдХреА рд╕рдВрдЦреНрдпрд╛ рдкрд░ 1 рдорд┐рдирдЯ рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдкрд░ рдирд┐рд░реНрднрд░рддрд╛ рджрд┐рдЦрд╛рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдЧреНрд░рд╛рдл:



рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╕реИрдХрдбрд╝реЛрдВ рдХрдиреЗрдХреНрд╢рдиреЛрдВ рдХреЗ рдмрд╛рдж, рджреЛрдиреЛрдВ рд╕рд░реНрд╡рд░реЛрдВ рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рддреЗрдЬреА рд╕реЗ рдЧрд┐рд░рддреА рд╣реИ (рдПрдХ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ, рдпрд╣ рдЕрдзрд┐рдХ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ)ред рдХреНрдпрд╛ рдпрд╣ рд▓рд┐рдирдХреНрд╕ рдЯреАрд╕реАрдкреА / рдЖрдИрдкреА рд╕реНрдЯреИрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ? рдЗрд╕ рддрд░рд╣ рдХреЗ рдЧреНрд░рд╛рдл рд╡реНрдпрд╡рд╣рд╛рд░ рдФрд░ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдмрд╣реБрд╕реНрддрд░реАрдп рдФрд░ рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рдЕрдиреБрдХреВрд▓рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдкрдиреА рдорд╛рдиреНрдпрддрд╛рдУрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВред




рдЬреИрд╕рд╛ рдХрд┐ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдпрд╣ рдкреНрд░рджрд░реНрд╢рди рдкрд░реАрдХреНрд╖рдг рд╡рд╛рд╕реНрддрд╡рд┐рдХ рднрд╛рд░ рдкрд░ рдЖрдИ / рдУ рд░рд┐рдПрдХреНрдЯрд░ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдирд╣реАрдВ рджрд┐рдЦрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд▓рдЧрднрдЧ рд╣рдореЗрд╢рд╛ рд╕рд░реНрд╡рд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░рддрд╛ рд╣реИ, рд▓реЙрдЧ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЯреАрдПрд▓рдПрд╕ рдХреЗ рд╕рд╛рде рдХреНрд░рд┐рдкреНрдЯреЛрдЧреНрд░рд╛рдлреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЖрджрд┐, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд▓реЛрдб рд╡рд┐рд╖рдо (рдЧрддрд┐рд╢реАрд▓) рд╣реИред рддреГрддреАрдп-рдкрдХреНрд╖ рдШрдЯрдХреЛрдВ рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг I / O рдкреНрд░реЛрдХреНрдЯрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд▓реЗрдЦ рдореЗрдВ рдЖрдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред


рдЖрдИ / рдУ рд░рд┐рдПрдХреНрдЯрд░ рдХреЗ рдиреБрдХрд╕рд╛рди


рдЖрдкрдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ I / O рд░рд┐рдПрдХреНрдЯрд░ рдХрдорд┐рдпрд╛рдВ рдХреЗ рдмрд┐рдирд╛ рдирд╣реАрдВ рд╣реИ, рдЕрд░реНрдерд╛рддреН:


  • рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ I / O рд░рд┐рдПрдХреНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдХреБрдЫ рдЕрдзрд┐рдХ рдХрдард┐рди рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдкреНрд░рд╡рд╛рд╣ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
  • рдЕрднреНрдпрд╛рд╕ рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рднрд╛рд░ рд╡рд┐рд╖рдо рд╣реИ, рдЬреЛ рдЗрд╕ рддрдереНрдп рдХреЛ рдЬрдиреНрдо рджреЗ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдзрд╛рдЧрд╛ рдиреАрдЪреЗ рд░рдЦрд╛ рдЬрд╛рдПрдЧрд╛ рдЬрдмрдХрд┐ рджреВрд╕рд░рд╛ рдХрд╛рдо рд╕реЗ рднрд░рд╛ рд╣реБрдЖ рд╣реИред
  • рдпрджрд┐ рдХреЛрдИ рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рд╕реНрдЯреНрд░реАрдо рдХреЛ рдмреНрд▓реЙрдХ рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╕рд┐рд╕реНрдЯрдо рд╕рд┐рд▓реЗрдХреНрдЯрд░ рдЦреБрдж рднреА рдмреНрд▓реЙрдХ рд╣реЛ рдЬрд╛рдПрдЧрд╛, рдЬрд┐рд╕рд╕реЗ рд╣рд╛рд░реНрдб-рдЯреВ-рдХреИрдЪ рдмрдЧ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред

рдЗрди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ I / O рдкреНрд░реЙрдХреНрдЯрд░ рджреНрд╡рд╛рд░рд╛ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрдХреНрд╕рд░ рдПрдХ рдЕрдиреБрд╕реВрдЪрдХ рдХреЗ рд╕рд╛рде рдЬреЛ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдереНрд░реЗрдб рдкреВрд▓ рдХреЛ рд▓реЛрдб рд╡рд┐рддрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдореЗрдВ рдПрдХ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдПрдкреАрдЖрдИ рднреА рд╣реИред рдЗрд╕рдХреА рдЪрд░реНрдЪрд╛ рдмрд╛рдж рдореЗрдВ рдореЗрд░реЗ рджреВрд╕рд░реЗ рд▓реЗрдЦ рдореЗрдВ рдХреА рдЬрд╛рдПрдЧреАред


рдирд┐рд╖реНрдХрд░реНрд╖


рдЗрд╕ рдкрд░, рдереНрдпреЛрд░реА рдкреНрд░реЛрдлрд╛рдЗрд▓рд░ рдореЗрдВ рд╕реАрдзреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рд╕реЗ рд╣рдорд╛рд░реА рдпрд╛рддреНрд░рд╛ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдИред


рдЗрд╕ рдкрд░ рдзреНрдпрд╛рди рди рджреЗрдВ, рдХреНрдпреЛрдВрдХрд┐ рдиреЗрдЯрд╡рд░реНрдХ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдХреЛ рд╕реБрд╡рд┐рдзрд╛ рдФрд░ рдЧрддрд┐ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рд╕реНрддрд░реЛрдВ рдХреЗ рд╕рд╛рде рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рдЕрдиреНрдп рд╕рдорд╛рди рд░реВрдк рд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИрдВред рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рд▓рд┐рдВрдХ рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рд╣реИрдВред


рдЬрд▓реНрдж рдорд┐рд▓рддреЗ рд╣реИрдВ!


рджрд┐рд▓рдЪрд╕реНрдк рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ



рдФрд░ рдХреНрдпрд╛ рдкрдврд╝рдирд╛ рд╣реИ?



Source: https://habr.com/ru/post/hi475896/


All Articles