io_submit: рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдХрднреА рдирд╣реАрдВ рд╕реБрдирд╛ рдЧрдпрд╛ рдПрдкреЛрд▓ рдХрд╛ рдПрдХ рд╡рд┐рдХрд▓реНрдк



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

рд▓реЗрдХрд┐рди рдПрдХ рдкрд▓ рд░реБрдХрд┐рдП! рдЖрдЦрд┐рд░, рдбрд┐рд╕реНрдХ рд╕реЗ рдбрд┐рд╕реНрдХ рдкрд░ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ I / O рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Linux AIO рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛! рдбрд┐рд╕реНрдХ рдкрд░ рдлрд╝рд╛рдЗрд▓реЗрдВ рдиреЗрдЯрд╡рд░реНрдХ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд╕рдорд╛рди рдирд╣реАрдВ рд╣реИрдВред рдХреНрдпрд╛ рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рднреА рд╕рдВрднрд╡ рд╣реИ?

рдпрд╣ рд╣рд╛рдБ рдирд┐рдХрд▓рддрд╛ рд╣реИ, рдпрд╣ рд╕рдВрднрд╡ рд╣реИ! рдпрд╣ рдЖрд▓реЗрдЦ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рддреЗрдЬреА рд╕реЗ рдФрд░ рдмреЗрд╣рддрд░ рдиреЗрдЯрд╡рд░реНрдХ рд╕рд░реНрд╡рд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдПрдкреАрдЖрдИ рдХреА рддрд╛рдХрдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред

рд▓реЗрдХрд┐рди рдЖрдЗрдП рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдХреНрдпрд╛ рд╣реИ, рдпрд╣ рдмрддрд╛рдХрд░ рд╢реБрд░реВ рдХрд░реЗрдВред

рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдХрд╛ рдкрд░рд┐рдЪрдп


рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдХреЗ рд▓рд┐рдП рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдбрд┐рд╕реНрдХ-рдЯреВ-рдбрд┐рд╕реНрдХ I / O рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред

рдРрддрд┐рд╣рд╛рд╕рд┐рдХ рд░реВрдк рд╕реЗ, рд▓рд┐рдирдХреНрд╕ рдкрд░, рд╕рднреА рдбрд┐рд╕реНрдХ рд╕рдВрдЪрд╛рд▓рди рдЕрд╡рд░реБрджреНрдз рдереЗред рдпрджрд┐ рдЖрдк open() , read() , write() рдпрд╛ fsync() , рддреЛ рд╕реНрдЯреНрд░реАрдо рддрдм рддрдХ рдмрдВрдж рд╣реЛ рдЬрд╛рддреА рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдореЗрдЯрд╛рдбрд╛рдЯрд╛ рдбрд┐рд╕реНрдХ рдХреИрд╢ рдореЗрдВ рдкреНрд░рдХрдЯ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдЖрдорддреМрд░ рдкрд░ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХрдИ рдЖрдИ / рдУ рд╕рдВрдЪрд╛рд▓рди рдФрд░ рдкрд░реНрдпрд╛рдкреНрдд рдореЗрдореЛрд░реА рдирд╣реАрдВ рд╣реИ, рддреЛ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдзреАрд░реЗ-рдзреАрд░реЗ рдХреИрд╢ рдХреЛ рднрд░ рджреЗрдВрдЧреЗ, рдФрд░ рд╕рдм рдХреБрдЫ рдЬрд▓реНрджреА рд╕реЗ рдкрд░реНрдпрд╛рдкреНрдд рдХрд╛рдо рдХрд░реЗрдЧрд╛ред

I / O рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдЙрдирдХреА рд╕рдВрдЦреНрдпрд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрддреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдбреЗрдЯрд╛рдмреЗрд╕ рдФрд░ рдкреНрд░реЙрдХреНрд╕реА рдХреЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВред рдРрд╕реЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП, рдПрдХ read() рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреВрд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд░реЛрдХрдирд╛ рдЕрд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИред

рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрдиреБрдкреНрд░рдпреЛрдЧ рддреАрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

  1. рдереНрд░реЗрдб рдкреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдФрд░ рдЕрд▓рдЧ рдереНрд░реЗрдбреНрд╕ рдкрд░ рдЕрд╡рд░реБрджреНрдз рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВред рдпрд╣ рдХреИрд╕реЗ POSIX AIO glibc рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ (рд▓рд┐рдирдХреНрд╕ AIO рдХреЗ рд╕рд╛рде рдЗрд╕реЗ рднреНрд░рдорд┐рдд рди рдХрд░реЗрдВ)ред рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП, рдЖрдИрдмреАрдПрдо рдкреНрд░рд▓реЗрдЦрди рджреЗрдЦреЗрдВред рдЗрд╕ рддрд░рд╣ рд╣рдордиреЗ рдХреНрд▓рд╛рдЙрдбрдлрд╝реЗрдпрд░ рдореЗрдВ рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рдХреА: рд╣рдо рдереНрд░реЗрдб рдкреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ read() рдФрд░ open() рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рддреЗ read() ред
  2. posix_fadvise(2) рд╕рд╛рде рдбрд┐рд╕реНрдХ рдХреИрд╢ рдХреЛ рдЧрд░реНрдо рдХрд░реЗрдВ рдФрд░ рд╕рд░реНрд╡рд╢реНрд░реЗрд╖реНрда рдХреЗ рд▓рд┐рдП рдЖрд╢рд╛ рдХрд░реЗрдВред
  3. XFS рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╕рд╛рде Linux AIO рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, O_DIRECT рдлрд╝реНрд▓реИрдЧ рдХреЗ рд╕рд╛рде рдлрд╛рдЗрд▓реЗрдВ рдЦреЛрд▓рдирд╛ рдФрд░ рдЕрдирдЪрд╛рд╣реА рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рдмрдЪрдирд╛ ред

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рддрд░реАрдХрд╛ рдЖрджрд░реНрд╢ рдирд╣реАрдВ рд╣реИред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд▓рд┐рдирдХреНрд╕ io_submit() , рдЬрдм рдмрд┐рдирд╛ рд╕реЛрдЪреЗ рд╕рдордЭреЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ io_submit() рдХреЙрд▓ рдореЗрдВ рдЕрд╡рд░реБрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рд╛рд▓ рд╣реА рдореЗрдВ LWN рдХреЗ рдПрдХ рдЕрдиреНрдп рд▓реЗрдЦ рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
"рд▓рд┐рдирдХреНрд╕ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ I / O рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЖрд▓реЛрдЪрдХ рдФрд░ рдХреБрдЫ рд╕рдорд░реНрдердХ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХрд╛рдВрд╢ рд▓реЛрдЧ рдЗрд╕рд╕реЗ рдХрдо рд╕реЗ рдХрдо рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХрддрд╛ рдХреА рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, AIO рдСрдкрд░реЗрд╢рди рдЙрди рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдХрдИ рдХрд╛рд░рдгреЛрдВ рд╕реЗ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдЕрд╡рд░реБрджреНрдз рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдХреЙрд▓рд┐рдВрдЧ рдереНрд░реЗрдб рдЗрд╕реЗ рдмрд░реНрджрд╛рд╢реНрдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред тАЭ
рдЕрдм рдЬрдм рд╣рдо рд▓рд┐рдирдХреНрд╕ AIO API рдХреА рдХрдордЬреЛрд░рд┐рдпреЛрдВ рдХреЛ рдЬрд╛рдирддреЗ рд╣реИрдВ, рддреЛ рдЖрдЗрдП рдЗрд╕рдХреА рдЦреВрдмрд┐рдпреЛрдВ рдкрд░ рдирдЬрд░ рдбрд╛рд▓рддреЗ рд╣реИрдВред

рд▓рд┐рдирдХреНрд╕ AIO рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдПрдХ рд╕рд░рд▓ рдХрд╛рд░реНрдпрдХреНрд░рдо


рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рд╕рднреА рдкрд╛рдВрдЪ рдЖрд╡рд╢реНрдпрдХ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЛ рд╕реНрд╡рдпрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ - рдЧреНрд▓рд┐рдмреНрдХ рдЙрдиреНрд╣реЗрдВ рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

  1. рдкрд╣рд▓реЗ рдЖрдкрдХреЛ aio_context рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП io_setup() рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдХрд░реНрдиреЗрд▓ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдПрдХ рдЕрдкрд╛рд░рджрд░реНрд╢реА рд╕реВрдЪрдХ рд▓реМрдЯрд╛рдПрдЧрд╛ред
  2. рдЙрд╕рдХреЗ рдмрд╛рдж, рдЖрдк io_submit() рдХреЛ "I / O рдирд┐рдпрдВрддреНрд░рдг рдЦрдВрдб" рдХреЗ рд╡реЗрдХреНрдЯрд░ рдХреЛ рдПрдХ рд╕рдВрд░рдЪрдирд╛ iocb рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрддрд╛рд░ рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВред
  3. рдЕрдм, рдЖрдЦрд┐рд░рдХрд╛рд░, рд╣рдо io_getevents() рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрддреНрддрд░ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рд╕рджрд┐рд╢ io_event рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд╡реЗрдХреНрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ - рдкреНрд░рддреНрдпреЗрдХ iocb рдмреНрд▓реЙрдХреЛрдВ рдХреЗ рдкрд░рд┐рдгрд╛рдоред

рдЖрда рдЖрдЬреНрдЮрд╛рдПрдБ рд╣реИрдВ рдЬреЛ рдЖрдк iocb рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рджреЛ рдХрдорд╛рдВрдб, рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рджреЛ, рджреЛ fsync рд╡рд┐рдХрд▓реНрдк, рдФрд░ POLL рдХрдорд╛рдВрдб, рдЬреЛ рдХрд░реНрдиреЗрд▓ рд╕рдВрд╕реНрдХрд░рдг 4.18 рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ (рдЖрдард╡рд╛рдВ рдХрдорд╛рдВрдб NOOP рд╣реИ):

 IOCB_CMD_PREAD = 0, IOCB_CMD_PWRITE = 1, IOCB_CMD_FSYNC = 2, IOCB_CMD_FDSYNC = 3, IOCB_CMD_POLL = 5,   /* from 4.18 */ IOCB_CMD_NOOP = 6, IOCB_CMD_PREADV = 7, IOCB_CMD_PWRITEV = 8, 

iocb , рдЬрд┐рд╕реЗ io_submit рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдХрд╛рдлреА рдмрдбрд╝реА рд╣реИ рдФрд░ рдбрд┐рд╕реНрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХреА рдЧрдИ рд╣реИред рдпрд╣рд╛рдБ рдЗрд╕рдХрд╛ рд╕рд░рд▓реАрдХреГрдд рд╕рдВрд╕реНрдХрд░рдг рд╣реИ:

 struct iocb { __u64 data;           /* user data */ ... __u16 aio_lio_opcode; /* see IOCB_CMD_ above */ ... __u32 aio_fildes;     /* file descriptor */ __u64 aio_buf;        /* pointer to buffer */ __u64 aio_nbytes;     /* buffer size */ ... } 

рдкреВрд░реНрдг io_event рд╕рдВрд░рдЪрдирд╛ рдЬреЛ io_getevents рджреЗрддрд╛ рд╣реИ:

 struct io_event { __u64  data; /* user data */ __u64  obj; /* pointer to request iocb */ __s64  res; /* result code for this event */ __s64  res2; /* secondary result */ }; 

рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИред рдПрдХ рд╕рд░рд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЬреЛ рд▓рд┐рдирдХреНрд╕ AIO API рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ / etc / passwd рдлрд╝рд╛рдЗрд▓ рдкрдврд╝рддрд╛ рд╣реИ:

 fd = open("/etc/passwd", O_RDONLY); aio_context_t ctx = 0; r = io_setup(128, &ctx); char buf[4096]; struct iocb cb = {.aio_fildes = fd,                 .aio_lio_opcode = IOCB_CMD_PREAD,                 .aio_buf = (uint64_t)buf,                 .aio_nbytes = sizeof(buf)}; struct iocb *list_of_iocb[1] = {&cb}; r = io_submit(ctx, 1, list_of_iocb); struct io_event events[1] = {{0}}; r = io_getevents(ctx, 1, 1, events, NULL); bytes_read = events[0].res; printf("read %lld bytes from /etc/passwd\n", bytes_read); 

рдкреВрд░реНрдг рд╕реНрд░реЛрдд рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, GitHub рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ ред рдпрд╣рд╛рдБ рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреА рдзрд╛рд░рд╛ рдЙрддреНрдкрд╛рджрди рд╣реИ:

 openat(AT_FDCWD, "/etc/passwd", O_RDONLY) io_setup(128, [0x7f4fd60ea000]) io_submit(0x7f4fd60ea000, 1, [{aio_lio_opcode=IOCB_CMD_PREAD, aio_fildes=3, aio_buf=0x7ffc5ff703d0, aio_nbytes=4096, aio_offset=0}]) io_getevents(0x7f4fd60ea000, 1, 1, [{data=0, obj=0x7ffc5ff70390, res=2494, res2=0}], NULL) 

рд╕рдм рдХреБрдЫ рдареАрдХ рдЪрд▓рд╛, рд▓реЗрдХрд┐рди рдбрд┐рд╕реНрдХ рд╕реЗ рдкрдврд╝рдирд╛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдирд╣реАрдВ рдерд╛: io_submit рдХреЙрд▓ рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рд╕рднреА рдХрд╛рдо рдХрд┐рдпрд╛ рдерд╛, io_getevents рдлрд╝рдВрдХреНрд╢рди io_getevents рддреБрд░рдВрдд рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ io_getevents ред рд╣рдо рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рдкрдврд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд▓рд┐рдП O_DIRECT рдзреНрд╡рдЬ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдбрд┐рд╕реНрдХ рд╕рдВрдЪрд╛рд▓рди рдХреИрд╢ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рддрд╛ рд╣реИред

рдЖрдЗрдП рдмреЗрд╣рддрд░ рдмрддрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдХреИрд╕реЗ io_submit рдирд┐рдпрдорд┐рдд рдлрд╝рд╛рдЗрд▓реЛрдВ рдкрд░ рд▓реЙрдХ рдХрд░рддрд╛ рд╣реИред рдпрд╣рд╛рдБ рдПрдХ рд╕рдорд╛рди рдЙрджрд╛рд╣рд░рдг рд╣реИ рдЬреЛ 1 GB рдмреНрд▓реЙрдХ рдХреЛ /dev/zero рд╕реЗ рдкрдврд╝рдиреЗ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд╕реНрдЯреНрд░реЗрд╕ рдХрд╛ рдЖрдЙрдЯрдкреБрдЯ рджрд┐рдЦрд╛рддрд╛ /dev/zero :

 io_submit(0x7fe1e800a000, 1, [{aio_lio_opcode=IOCB_CMD_PREAD, aio_fildes=3, aio_buf=0x7fe1a79f4000, aio_nbytes=1073741824, aio_offset=0}]) \   = 1 <0.738380> io_getevents(0x7fe1e800a000, 1, 1, [{data=0, obj=0x7fffb9588910, res=1073741824, res2=0}], NULL) \   = 1 <0.000015> 

рдХрд░реНрдиреЗрд▓ рдиреЗ io_submit рдХреЙрд▓ рдкрд░ 738 ms рдЦрд░реНрдЪ рдХрд┐рдП io_submit рдФрд░ io_getevents рдкрд░ рдХреЗрд╡рд▓ 15 nsред рдпрд╣ рдиреЗрдЯрд╡рд░реНрдХ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд╕рд╛рде рд╕рдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддрд╛ рд╣реИ - рд╕рднреА рдХрд╛рдо io_submit рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рдлреЛрдЯреЛ рд╣реЗрд▓рд┐рдХреНрд╕84 рд╕реАрд╕реА / рдмрд╛рдп-рдПрд╕рдП / 3.0

рд▓рд┐рдирдХреНрд╕ AIO рдФрд░ рдиреЗрдЯрд╡рд░реНрдХ


io_submit рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛рдлреА рд░реВрдврд╝рд┐рд╡рд╛рджреА рд╣реИ: рдпрджрд┐ рдЙрддреНрддреАрд░реНрдг рдлрд╝рд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХреЛ O_DIRECT рдзреНрд╡рдЬ рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рдЦреЛрд▓рд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдлрд╝рдВрдХреНрд╢рди рдмрд╕ рдмреНрд▓реЙрдХ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░рддрд╛ рд╣реИред рдиреЗрдЯрд╡рд░реНрдХ рдХрдиреЗрдХреНрд╢рди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐:

  • рдЕрд╡рд░реБрджреНрдз рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП, IOCV_CMD_PREAD рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреИрдХреЗрдЯ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдЧрд╛;
  • рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП, IOCB_CMD_PREAD рдХреЛрдб -11 (EAGAIN) рд▓реМрдЯрд╛рдПрдЧрд╛ред

рд╕рдорд╛рди рд╢рдмреНрджрд╛рд░реНрде рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд┐рдпрдорд┐рдд read() рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдореЗрдВ рднреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдиреЗрдЯрд╡рд░реНрдХ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп io_submit рдЕрдЪреНрдЫреЗ рдкреБрд░рд╛рдиреЗ read() / write() рдХреЙрд▓ рд╕реЗ рдЕрдзрд┐рдХ рд╕реНрдорд╛рд░реНрдЯ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

рдпрд╣ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ iocb рдЕрдиреБрд░реЛрдз рдХрд░реНрдиреЗрд▓ рджреНрд╡рд╛рд░рд╛ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдП iocb ред

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

рдпрджрд┐ рд╡реЗрдм рд╕рд░реНрд╡рд░ рдХреЛ рд╕реИрдХрдбрд╝реЛрдВ рдиреЗрдЯрд╡рд░реНрдХ рдХрдиреЗрдХреНрд╢рди рд╕реЗ рдбреЗрдЯрд╛ рднреЗрдЬрдиреЗ рдФрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ io_submit рдХрд╛ рдЙрдкрдпреЛрдЧ io_submit рдПрдХ рдорд╣рд╛рди рд╡рд┐рдЪрд╛рд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕реИрдХрдбрд╝реЛрдВ рднреЗрдЬрдиреЗ рдФрд░ рдкреБрди: рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рдмрдЪрддрд╛ рд╣реИред рдпрд╣ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░реЗрдЧрд╛ - рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдЬрдЧрд╣ рд╕реЗ рдХрд░реНрдиреЗрд▓ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдирд╛ рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд рдореБрдХреНрдд рдирд╣реАрдВ рд╣реИ, рдЦрд╛рд╕рдХрд░ рд╕реНрдкреЗрдХреНрдЯреНрд░рдо рдФрд░ рдореЗрд▓реНрдЯрдбрд╛рдЙрди рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рдЙрдкрд╛рдпреЛрдВ рдХреА рд╢реБрд░реВрдЖрдд рдХреЗ рдмрд╛рджред

рдПрдХ рдмрдлрд░
рдПрдХрд╛рдзрд┐рдХ рдмрдлрд╝рд░реНрд╕
рдПрдХ рдлрд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░
рдкрдврд╝реЗрдВ ()
рд░реАрдбрд╡ ()
рдорд▓реНрдЯреАрдкрд▓ рдлрд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░реНрд╕
io_submit + IOCB_CMD_PREAD
io_submit + IOCB_CMD_PREADV

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

 while True: d = sd1.read(4096) sd2.write(d) 

рд╣рдо рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдорд╛рди рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╡реНрдпрдХреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдХреЛрдб рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧрд╛:

 struct iocb cb[2] = {{.aio_fildes = sd2,                     .aio_lio_opcode = IOCB_CMD_PWRITE,                     .aio_buf = (uint64_t)&buf[0],                     .aio_nbytes = 0},                    {.aio_fildes = sd1,                    .aio_lio_opcode = IOCB_CMD_PREAD,                    .aio_buf = (uint64_t)&buf[0],                    .aio_nbytes = BUF_SZ}}; struct iocb *list_of_iocb[2] = {&cb[0], &cb[1]}; while(1) { r = io_submit(ctx, 2, list_of_iocb); struct io_event events[2] = {}; r = io_getevents(ctx, 2, 2, events, NULL); cb[0].aio_nbytes = events[1].res; } 

рдпрд╣ рдХреЛрдб io_submit рджреЛ рдХрд╛рд░реНрдп рдЬреЛрдбрд╝рддрд╛ рд╣реИ: рдкрд╣рд▓реЗ io_submit рд▓рд┐рдП рдПрдХ sd2 рдЕрдиреБрд░реЛрдз, рдФрд░ рдлрд┐рд░ sd1 рд╕реЗ рдПрдХ рдкрдврд╝рдиреЗ рдХрд╛ рдЕрдиреБрд░реЛрдзред рдкрдврд╝рдиреЗ рдХреЗ рдмрд╛рдж, рдХреЛрдб рд▓рд┐рдЦрдиреЗ рд╡рд╛рд▓реЗ рдмрдлрд░ рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рд╕рд╣реА рдХрд░рддрд╛ рд╣реИ рдФрд░ рд▓реВрдк рдХреЛ рд╢реБрд░реБрдЖрдд рд╕реЗ рджреЛрд╣рд░рд╛рддрд╛ рд╣реИред рдПрдХ рдЪрд╛рд▓ рд╣реИ: рдкрд╣рд▓реА рдмрд╛рд░ рдПрдХ рд▓реЗрдЦрди рдЖрдХрд╛рд░ рдХреЗ рдмрдлрд░ рдХреЗ рд╕рд╛рде рд╣реЛрддрд╛ рд╣реИ 0. рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд▓рд┐рдЦрдиреЗ рдХреА рдХреНрд╖рдорддрд╛ + рдПрдХ io_submit рдХреЙрд▓ рдореЗрдВ рдкрдврд╝рдиреЗ (рд▓реЗрдХрд┐рди рдкрдврд╝рдиреЗ + рд▓рд┐рдЦрдиреЗ рдирд╣реАрдВ) рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред

рдХреНрдпрд╛ рдпрд╣ рдХреЛрдб рд░реЗрдЧреБрд▓рд░ read() / write() рд╕реЗ рдЬреНрдпрд╛рджрд╛ рддреЗрдЬ рд╣реИ? рдЕрднреА рдирд╣реАрдВред рджреЛрдиреЛрдВ рд╕рдВрд╕реНрдХрд░рдг рджреЛ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ: рд░реАрдб + рд░рд╛рдЗрдЯ рдФрд░ io_submit + io_geteventsред рд▓реЗрдХрд┐рди, рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдХреЛрдб рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

Io_getevents рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛ рд░рд╣рд╛ рд╣реИ


рд░рдирдЯрд╛рдЗрдо io_setup() рдХрд░реНрдиреЗрд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдХреЗ рдХрдИ рдкреЗрдЬ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рд╕реЗ рдпрд╣ рдореЗрдореЛрд░реА рдмреНрд▓реЙрдХ / proc // рдореИрдкреНрд╕ рдореЗрдВ рджрд┐рдЦрддрд╛ рд╣реИ:

 marek:~$ cat /proc/`pidof -s aio_passwd`/maps ... 7f7db8f60000-7f7db8f63000 rw-s 00000000 00:12 2314562     /[aio] (deleted) ... 

рдореЗрдореЛрд░реА рдмреНрд▓реЙрдХ [aio] (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ 12 Kb) рдХреЛ io_setup рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рд░реНрдХреБрд▓рд░ рдмрдлрд░ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рдШрдЯрдирд╛рдУрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, io_getevents рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рд╣реИ - рдЗрд╡реЗрдВрдЯ рдкреВрд░рд╛ рд╣реЛрдиреЗ рд╡рд╛рд▓рд╛ рдбреЗрдЯрд╛ рд░рд┐рдВрдЧ рдмрдлрд░ рд╕реЗ рдХрд░реНрдиреЗрд▓ рдореЛрдб рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрд┐рдирд╛ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣рд╛рдБ рдХреЛрдб рдХрд╛ рд╕рд╣реА рд╕рдВрд╕реНрдХрд░рдг рд╣реИ:

 int io_getevents(aio_context_t ctx, long min_nr, long max_nr,                struct io_event *events, struct timespec *timeout) {   int i = 0;   struct aio_ring *ring = (struct aio_ring*)ctx;   if (ring == NULL || ring->magic != AIO_RING_MAGIC) {       goto do_syscall;   }   while (i < max_nr) {       unsigned head = ring->head;       if (head == ring->tail) {           /* There are no more completions */           break;       } else {           /* There is another completion to reap */           events[i] = ring->events[head];           read_barrier();           ring->head = (head + 1) % ring->nr;           i++;       }   }   if (i == 0 && timeout != NULL && timeout->tv_sec == 0 && timeout->tv_nsec == 0) {       /* Requested non blocking operation. */       return 0;   }   if (i && i >= min_nr) {       return i;   } do_syscall:   return syscall(__NR_io_getevents, ctx, min_nr-i, max_nr-i, &events[i], timeout); } 

рдХреЛрдб рдХрд╛ рдкреВрд░рд╛ рд╕рдВрд╕реНрдХрд░рдг GitHub рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИ ред рдЗрд╕ рд░рд┐рдВрдЧ рдмрдлрд╝рд░ рдХреЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдЦрд░рд╛рдм рд░реВрдк рд╕реЗ рдкреНрд░рд▓реЗрдЦрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ; рд▓реЗрдЦрдХ рдиреЗ рдХреЛрдб рдХреЛ axboe / fio рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рд╣реИред

рдЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рдж, рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЛрдб рдХреЗ рд╣рдорд╛рд░реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд▓реВрдк рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреЛ рдЗрд╕реЗ рд░реАрдб + рд░рд╛рдЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореВрд▓ рдХреЛрдб рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдереЛрдбрд╝рд╛ рддреЗрдЬ рдмрдирд╛рддрд╛ рд╣реИред


рдлреЛрдЯреЛ рдЯреНрд░реЗрди рддрд╕реНрд╡реАрд░реЗрдВ CC / BY-SA / 2.0

рдПрдкреЛрд▓ рд╡рд┐рдХрд▓реНрдк


IOCB_CMD_POLL рдХреЗ рдХрд░реНрдиреЗрд▓ рд╕рдВрд╕реНрдХрд░рдг 4.18 рдХреЗ рд╕рд╛рде, io_submit рдЪрдпрди / рдкреЛрд▓ / рдПрдкреЛрд▓ рдХреЗ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЧрдпрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдХреЛрдб рдиреЗрдЯрд╡рд░реНрдХ рдХрдиреЗрдХреНрд╢рди рд╕реЗ рдбреЗрдЯрд╛ рдХреА рдЙрдореНрдореАрдж рдХрд░реЗрдЧрд╛:

 struct iocb cb = {.aio_fildes = sd,                 .aio_lio_opcode = IOCB_CMD_POLL,                 .aio_buf = POLLIN}; struct iocb *list_of_iocb[1] = {&cb}; r = io_submit(ctx, 1, list_of_iocb); r = io_getevents(ctx, 1, 1, events, NULL); 

рдкреВрд░реНрдг рдХреЛрдб ред рдпрд╣рд╛рдБ рдЙрд╕рдХрд╛ рд╕реНрдЯреНрд░реЗрд╕ рдЖрдЙрдЯрдкреБрдЯ рд╣реИ:

 io_submit(0x7fe44bddd000, 1, [{aio_lio_opcode=IOCB_CMD_POLL, aio_fildes=3}]) \   = 1 <0.000015> io_getevents(0x7fe44bddd000, 1, 1, [{data=0, obj=0x7ffef65c11a8, res=1, res2=0}], NULL) \   = 1 <1.000377> 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕ рдмрд╛рд░ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХрд╛рдо рдХрд┐рдпрд╛: io_submit рддреБрд░рдВрдд рдирд┐рд╖реНрдкрд╛рджрд┐рдд, рдФрд░ io_getevents рдПрдХ рд╕реЗрдХрдВрдб рдХреЗ рд▓рд┐рдП рдЕрд╡рд░реБрджреНрдз, рдбреЗрдЯрд╛ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣рд╛ рд╣реИред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ epoll_wait() рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЗ рдмрдЬрд╛рдп рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, epoll рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдорддреМрд░ рдкрд░ epoll_ctl рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдкрд░ рд▓рдЧрд╛рддрд╛рд░ рдХреЙрд▓ рд╕реЗ рдмрдЪрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ - рдХрд╛рд░рдгреЛрдВ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ рдореИрдиреБрдЕрд▓ рдореЗрдВ EPOLLONESHOT рдФрд░ EPOLLET рдЭрдВрдбреЗ рдкрдврд╝реЗрдВ ред рдХрдиреЗрдХреНрд╢рди рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП io_submit рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рдЗрди рдХрдард┐рдирд╛рдЗрдпреЛрдВ рдФрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рд╕реЗ рдмрдЪ рд╕рдХрддреЗ рд╣реИрдВред рдмрд╕ iocb рд╡реЗрдХреНрдЯрд░ рд╕реЗ рдХрдиреЗрдХреНрд╢рди рдЬреЛрдбрд╝реЗрдВ, io_submit рдХреЛ рдПрдХ рдмрд╛рд░ рдХреЙрд▓ рдХрд░реЗрдВ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВред рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИред

рд╕рд╛рд░рд╛рдВрд╢


рдЗрд╕ рдкреЛрд╕реНрдЯ рдореЗрдВ, рд╣рдордиреЗ рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдПрдкреАрдЖрдИ рдХреЛ рдХрд╡рд░ рдХрд┐рдпрд╛ред рдпрд╣ рдПрдкреАрдЖрдИ рдореВрд▓ рд░реВрдк рд╕реЗ рдбрд┐рд╕реНрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдиреЗрдЯрд╡рд░реНрдХ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд╕рд╛рде рднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдирд┐рдпрдорд┐рдд рдкрдврд╝рдиреЗ () + рд▓рд┐рдЦрдиреЗ () рдХреЙрд▓реЛрдВ рдХреЗ рд╡рд┐рдкрд░реАрдд, io_submit рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЖрдк рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЛ рд╕рдореВрд╣реАрдХреГрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдкреНрд░рджрд░реНрд╢рди рдмрдврд╝рд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдиреЗрдЯрд╡рд░реНрдХ рдХрдиреЗрдХреНрд╢рди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрд░реНрдиреЗрд▓ рд╕рдВрд╕реНрдХрд░рдг 4.18, io_submit io_getevents рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдирд╛, POLLIN рдФрд░ POLLOUT рдлреЙрд░реНрдо рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ epoll() рд▓рд┐рдП рдПрдХ рд╡рд┐рдХрд▓реНрдк рд╣реИред

рдореИрдВ рдПрдХ рдРрд╕реА рдиреЗрдЯрд╡рд░реНрдХ рд╕реЗрд╡рд╛ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдЬреЛ рдкрдврд╝рдиреЗ, рд▓рд┐рдЦрдиреЗ, epoll_ctl рдФрд░ epoll_wait рдХреЗ рдорд╛рдирдХ рд╕реЗрдЯ рдХреЗ рдмрдЬрд╛рдп рдХреЗрд╡рд▓ io_submit io_getevents рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, io_submit рдореЗрдВ рд╕рдореВрд╣ рдХреЙрд▓рд┐рдВрдЧ рдкреНрд░рдгрд╛рд▓реА рдПрдХ рдмрдбрд╝рд╛ рд▓рд╛рдн рджреЗ рд╕рдХрддреА рд╣реИ, рдРрд╕рд╛ рд╕рд░реНрд╡рд░ рдмрд╣реБрдд рддреЗрдЬ рд╣реЛрдЧрд╛ред

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдПрдкреАрдЖрдИ рдореЗрдВ рд╣рд╛рд▓ рдХреЗ рд╕реБрдзрд╛рд░реЛрдВ рдХреЗ рдмрд╛рдж рднреА, рдЗрд╕рдХреА рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд░реНрдЪрд╛ рдЬрд╛рд░реА рд╣реИред рдпрд╣ рд╕рд░реНрд╡рд╡рд┐рджрд┐рдд рд╣реИ рдХрд┐ рд▓рд┐рдирд╕ рдЙрд╕рд╕реЗ рдирдлрд░рдд рдХрд░рддрд╛ рд╣реИ :

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

рдХреЙрд▓рд┐рдВрдЧ рдФрд░ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕реА рдХреЗ рд▓рд┐рдП рдПрдХ рдмреЗрд╣рддрд░ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдП рдЧрдП рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдирдореЗрдВ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рджреГрд╖реНрдЯрд┐ рдХрд╛ рдЕрднрд╛рд╡ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, sendto (MSG_ZEROCOPY) рдХрд╛ рд╣рд╛рд▓рд┐рдпрд╛ рдЬреЛрдбрд╝ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдбреЗрдЯрд╛ рд╣рд╕реНрддрд╛рдВрддрд░рдг рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рдореВрд╣реАрдХрд░рдг рдХреЗ рд▓рд┐рдП рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред io_submit рд╕рдореВрд╣реАрдХрд░рдг рдХреЗ рд▓рд┐рдП рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдирд╣реАрдВред рдЗрд╕рд╕реЗ рднреА рдмрджрддрд░ - рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд▓рд┐рдирдХреНрд╕ рдкрд░ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдШрдЯрдирд╛рдУрдВ рдХреЛ рд╡рд┐рддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рддреАрди рддрд░реАрдХреЗ рд╣реИрдВ: рд╕рд┐рдЧреНрдирд▓, io_getevents рдФрд░ MSG_ERRQUEUEред

рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИ рдХрд┐ рдиреЗрдЯрд╡рд░реНрдХ рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рдХрд╛рдо рдХреЛ рдЧрддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдирдП рддрд░реАрдХреЗ рд╣реИрдВред

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


All Articles