
рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдорддрджрд╛рди рдХреЗ рд▓рд┐рдП рдПрдХ рдирдП рдХрд░реНрдиреЗрд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓реЗрдЦрдХ рдХрд╛ рдзреНрдпрд╛рди LWN рдХреЗ рдПрдХ рд▓реЗрдЦ рдХреА рдУрд░ рдЖрдХрд░реНрд╖рд┐рдд рд╣реБрдЖред рдпрд╣ рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдПрдкреАрдЖрдИ (рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдлрд╝рд╛рдЗрд▓ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕) рдореЗрдВ рдирдП рдорддрджрд╛рди рддрдВрддреНрд░ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдХрд░реНрдиреЗрд▓ рд╕рдВрд╕реНрдХрд░рдг 4.18 рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ред рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдХрд╛рдлреА рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ: рдкреИрдЪ рдХрд╛ рд▓реЗрдЦрдХ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реИред
рд▓реЗрдХрд┐рди рдПрдХ рдкрд▓ рд░реБрдХрд┐рдП! рдЖрдЦрд┐рд░, рдбрд┐рд╕реНрдХ рд╕реЗ рдбрд┐рд╕реНрдХ рдкрд░ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ I / O рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Linux AIO рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛! рдбрд┐рд╕реНрдХ рдкрд░ рдлрд╝рд╛рдЗрд▓реЗрдВ рдиреЗрдЯрд╡рд░реНрдХ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд╕рдорд╛рди рдирд╣реАрдВ рд╣реИрдВред рдХреНрдпрд╛ рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рднреА рд╕рдВрднрд╡ рд╣реИ?
рдпрд╣ рд╣рд╛рдБ рдирд┐рдХрд▓рддрд╛ рд╣реИ, рдпрд╣ рд╕рдВрднрд╡ рд╣реИ! рдпрд╣ рдЖрд▓реЗрдЦ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рддреЗрдЬреА рд╕реЗ рдФрд░ рдмреЗрд╣рддрд░ рдиреЗрдЯрд╡рд░реНрдХ рд╕рд░реНрд╡рд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдПрдкреАрдЖрдИ рдХреА рддрд╛рдХрдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред
рд▓реЗрдХрд┐рди рдЖрдЗрдП рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдХреНрдпрд╛ рд╣реИ, рдпрд╣ рдмрддрд╛рдХрд░ рд╢реБрд░реВ рдХрд░реЗрдВред
рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдХрд╛ рдкрд░рд┐рдЪрдп
рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдХреЗ рд▓рд┐рдП рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдбрд┐рд╕реНрдХ-рдЯреВ-рдбрд┐рд╕реНрдХ I / O рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
рдРрддрд┐рд╣рд╛рд╕рд┐рдХ рд░реВрдк рд╕реЗ, рд▓рд┐рдирдХреНрд╕ рдкрд░, рд╕рднреА рдбрд┐рд╕реНрдХ рд╕рдВрдЪрд╛рд▓рди рдЕрд╡рд░реБрджреНрдз рдереЗред рдпрджрд┐ рдЖрдк
open()
,
read()
,
write()
рдпрд╛
fsync()
, рддреЛ рд╕реНрдЯреНрд░реАрдо рддрдм рддрдХ рдмрдВрдж рд╣реЛ рдЬрд╛рддреА рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдореЗрдЯрд╛рдбрд╛рдЯрд╛ рдбрд┐рд╕реНрдХ рдХреИрд╢ рдореЗрдВ рдкреНрд░рдХрдЯ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдЖрдорддреМрд░ рдкрд░ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХрдИ рдЖрдИ / рдУ рд╕рдВрдЪрд╛рд▓рди рдФрд░ рдкрд░реНрдпрд╛рдкреНрдд рдореЗрдореЛрд░реА рдирд╣реАрдВ рд╣реИ, рддреЛ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдзреАрд░реЗ-рдзреАрд░реЗ рдХреИрд╢ рдХреЛ рднрд░ рджреЗрдВрдЧреЗ, рдФрд░ рд╕рдм рдХреБрдЫ рдЬрд▓реНрджреА рд╕реЗ рдкрд░реНрдпрд╛рдкреНрдд рдХрд╛рдо рдХрд░реЗрдЧрд╛ред
I / O рд╕рдВрдЪрд╛рд▓рди рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдЙрдирдХреА рд╕рдВрдЦреНрдпрд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрддреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдбреЗрдЯрд╛рдмреЗрд╕ рдФрд░ рдкреНрд░реЙрдХреНрд╕реА рдХреЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВред рдРрд╕реЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП, рдПрдХ
read()
рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреВрд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд░реЛрдХрдирд╛ рдЕрд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИред
рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрдиреБрдкреНрд░рдпреЛрдЧ рддреАрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
- рдереНрд░реЗрдб рдкреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдФрд░ рдЕрд▓рдЧ рдереНрд░реЗрдбреНрд╕ рдкрд░ рдЕрд╡рд░реБрджреНрдз рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВред рдпрд╣ рдХреИрд╕реЗ POSIX AIO glibc рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ (рд▓рд┐рдирдХреНрд╕ AIO рдХреЗ рд╕рд╛рде рдЗрд╕реЗ рднреНрд░рдорд┐рдд рди рдХрд░реЗрдВ)ред рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП, рдЖрдИрдмреАрдПрдо рдкреНрд░рд▓реЗрдЦрди рджреЗрдЦреЗрдВред рдЗрд╕ рддрд░рд╣ рд╣рдордиреЗ рдХреНрд▓рд╛рдЙрдбрдлрд╝реЗрдпрд░ рдореЗрдВ рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рдХреА: рд╣рдо рдереНрд░реЗрдб рдкреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ
read()
рдФрд░ open()
рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рддреЗ read()
ред
posix_fadvise(2)
рд╕рд╛рде рдбрд┐рд╕реНрдХ рдХреИрд╢ рдХреЛ рдЧрд░реНрдо рдХрд░реЗрдВ рдФрд░ рд╕рд░реНрд╡рд╢реНрд░реЗрд╖реНрда рдХреЗ рд▓рд┐рдП рдЖрд╢рд╛ рдХрд░реЗрдВред
- XFS рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╕рд╛рде Linux AIO рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, O_DIRECT рдлрд╝реНрд▓реИрдЧ рдХреЗ рд╕рд╛рде рдлрд╛рдЗрд▓реЗрдВ рдЦреЛрд▓рдирд╛ рдФрд░ рдЕрдирдЪрд╛рд╣реА рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рдмрдЪрдирд╛ ред
рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рддрд░реАрдХрд╛ рдЖрджрд░реНрд╢ рдирд╣реАрдВ рд╣реИред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд▓рд┐рдирдХреНрд╕
io_submit()
, рдЬрдм рдмрд┐рдирд╛ рд╕реЛрдЪреЗ рд╕рдордЭреЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ
io_submit()
рдХреЙрд▓ рдореЗрдВ рдЕрд╡рд░реБрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рд╛рд▓ рд╣реА рдореЗрдВ
LWN рдХреЗ рдПрдХ рдЕрдиреНрдп
рд▓реЗрдЦ рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
"рд▓рд┐рдирдХреНрд╕ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ I / O рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЖрд▓реЛрдЪрдХ рдФрд░ рдХреБрдЫ рд╕рдорд░реНрдердХ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХрд╛рдВрд╢ рд▓реЛрдЧ рдЗрд╕рд╕реЗ рдХрдо рд╕реЗ рдХрдо рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХрддрд╛ рдХреА рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, AIO рдСрдкрд░реЗрд╢рди рдЙрди рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдХрдИ рдХрд╛рд░рдгреЛрдВ рд╕реЗ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдЕрд╡рд░реБрджреНрдз рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдХреЙрд▓рд┐рдВрдЧ рдереНрд░реЗрдб рдЗрд╕реЗ рдмрд░реНрджрд╛рд╢реНрдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред тАЭ
рдЕрдм рдЬрдм рд╣рдо рд▓рд┐рдирдХреНрд╕ AIO API рдХреА рдХрдордЬреЛрд░рд┐рдпреЛрдВ рдХреЛ рдЬрд╛рдирддреЗ рд╣реИрдВ, рддреЛ рдЖрдЗрдП рдЗрд╕рдХреА рдЦреВрдмрд┐рдпреЛрдВ рдкрд░ рдирдЬрд░ рдбрд╛рд▓рддреЗ рд╣реИрдВред
рд▓рд┐рдирдХреНрд╕ AIO рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдПрдХ рд╕рд░рд▓ рдХрд╛рд░реНрдпрдХреНрд░рдо
рд▓рд┐рдирдХреНрд╕ рдПрдЖрдИрдУ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдкрд╣рд▓реЗ
рд╕рднреА рдкрд╛рдВрдЪ рдЖрд╡рд╢реНрдпрдХ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХреЛ рд╕реНрд╡рдпрдВ
рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ - рдЧреНрд▓рд┐рдмреНрдХ рдЙрдиреНрд╣реЗрдВ рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
- рдкрд╣рд▓реЗ рдЖрдкрдХреЛ
aio_context
рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП io_setup()
рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдХрд░реНрдиреЗрд▓ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдПрдХ рдЕрдкрд╛рд░рджрд░реНрд╢реА рд╕реВрдЪрдХ рд▓реМрдЯрд╛рдПрдЧрд╛ред
- рдЙрд╕рдХреЗ рдмрд╛рдж, рдЖрдк
io_submit()
рдХреЛ "I / O рдирд┐рдпрдВрддреНрд░рдг рдЦрдВрдб" рдХреЗ рд╡реЗрдХреНрдЯрд░ рдХреЛ рдПрдХ рд╕рдВрд░рдЪрдирд╛ iocb рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрддрд╛рд░ рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВред
- рдЕрдм, рдЖрдЦрд┐рд░рдХрд╛рд░, рд╣рдо
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ред
рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИ рдХрд┐ рдиреЗрдЯрд╡рд░реНрдХ рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рдХрд╛рдо рдХреЛ рдЧрддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдирдП рддрд░реАрдХреЗ рд╣реИрдВред