Linuxda epoll va io_uring: Asinxron I/O texnologiyalarining taqqoslanishi
21-iyun, 2026, 04:090 ko'rish3 daqiqa o'qish
Linux operatsion tizimida tarmoqli serverlar, ma'lumotlar bazalari yoki har qanday yuqori yukli ilovalar asinxron I/O mexanizmlariga tayanadi. Eng ko‘p ishlatiladigan ikki usul – epoll va io_uring. Ushbu maqolada ularning ishlash printsipi, afzalliklari va kamchiliklari, shuningdek amaliy kod misollari ko‘rib chiqiladi.
epoll – an'anaviy tayyorlik modeli
2002‑yilda Linux kerneliga kiritilgan epoll, dasturchilarga fayl descriptorlari (socket, fayl, pipe) bo‘yicha "tayyor" holatni kuzatish imkonini beradi. Dastur epoll instance yaratadi, descriptorlarni ro‘yxatga qo‘shadi (epoll_ctl) va epoll_wait chaqirig‘i orqali hodisalar kelishini kutadi. Hodisa kelganda, dastur read yoki write kabi amallarni bajaradi.
- Har bir I/O operatsiyasi uchun kamida ikki sistem chaqirig‘i (epoll_wait + read/write) kerak.
- Bu chaqiruvlar foydalanuvchi‑kernel kontekst o‘zgartirishiga olib keladi, natijada yuk ko‘payganda latensiya oshadi.
- Soddaligi va keng qo‘llab‑quvvatlanishi tufayli ko‘plab eski dasturlarda (nginx, haproxy) asosiy mexanizm sifatida ishlatiladi.
io_uring – zamonaviy yakunlanish modeli
2019‑yilda Linux 5.1 kernelida taqdim etilgan io_uring, asinxron I/O ni yakunlanish (completion) asosida boshqaradi. Dastur kernel bilan umumiy xotira (ring buffer) orqali muloqot qiladi: submission queue (SQ) ga amallarni qo‘shadi, kernel ularni bajaradi va completion queue (CQ) ga natijalarni yozadi.
- Bir martalik
io_uring_setup chaqirig‘i orqali ring yaratilib, keyingi amallar paket (batch) ko‘rinishida yuboriladi.
- Har bir paket uchun bitta
io_uring_enter chaqirig‘i yetarli, bu esa sistem chaqiruvlar sonini sezilarli darajada kamaytiradi.
- Sqpoll (IORING_SETUP_SQPOLL) rejimi bilan kernel alohida ip (thread) orqali SQ ni doimiy tekshiradi – bu holatda foydalanuvchi kodda deyarli hech qanday sistem chaqiruv yo‘q, lekin CPU resurslari sarflanadi.
Taqqoslash jadvali
| Xususiyat | epoll | io_uring |
| Model | Tayyorlik (ready) | Yakunlanish (completion) |
| Sistem chaqiruvlar | Har I/O uchun 2+ | Har paket uchun 1 (yoki 0 SQPOLL bilan) |
| Zero‑copy imkoniyati | Cheklangan | io_uring_register_buffers orqali to‘liq |
| CPU yuklamasi | O‘rtacha | Sqpollda ip ishlatiladi – CPU sarfi oshadi |
| Qo‘llab‑quvvatlash | Keng (kernel 2.6+) | Kernel 5.1+ (yangi distro’larda) |
Amaliy kod misollari
epoll misoli (C)
#include <sys/epoll.h>
int epfd = epoll_create1(0);
struct epoll_event ev = { .events = EPOLLIN, .data.fd = STDIN_FILENO };
epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev);
while (1) {
struct epoll_event events[10];
int n = epoll_wait(epfd, events, 10, -1);
for (int i = 0; i < n; ++i) {
char buf[1024];
read(events[i].data.fd, buf, sizeof(buf));
}
}
io_uring misoli (C, liburing)
#include <liburing.h>
struct io_uring ring;
io_uring_queue_init(8, &ring, 0);
struct io_uring_sqe *sqe = io_uring_get_sqe(&ring);
io_uring_prep_read(sqe, STDIN_FILENO, buf, sizeof(buf), 0);
io_uring_submit(&ring);
struct io_uring_cqe *cqe;
io_uring_wait_cqe(&ring, &cqe);
// buf ichidagi ma'lumotlar tayyor
io_uring_cqe_seen(&ring, cqe);
Qachon qaysi texnologiyani tanlash kerak?
- Legacy tizimlar – kernel versiyasi eski bo‘lsa, epoll hali ham birinchi tanlov.
- Yangi serverlar – yuqori yuk, ko‘p aloqalar va minimal latensiya talab qilinsa, io_uring afzallik beradi.
- Zero‑copy talab qilinadigan tarmoq ilovalari (masalan, HTTP/2, gRPC) – io_uring bilan bu imkoniyat to‘liq amalga oshiriladi.
- CPU resurslari cheklangan – SQPOLL o‘rniga oddiy io_uring_enter bilan paketli yuborish yetarli bo‘lishi mumkin.
Xulosa
epoll Linuxda uzoq yillik tajribaga ega, ammo har bir I/O operatsiyasini alohida sistem chaqiruvga majbur qiladi. io_uring esa bir martalik sozlash va paketli amallar orqali sistem chaqiruvlarni kamaytiradi, zero‑copy va boshqa ilg‘or funksiyalarni taklif etadi. Zamonaviy Linux serverlarida, ayniqsa yangi kernel versiyalarida, io_uring asinxron I/O ning de‑facto standartiga aylangan. Shuning uchun yangi loyihalar yoki mavjud ilovalarni modernizatsiya qilishda io_uring ni ko‘rib chiqish tavsiya etiladi.