Divni markazlashtirish: qiyinchiliklar va yechimlar
Divni markazlashtirish uchun yangi usullar va ularning cheklovlariga oid maqola

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.
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.
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.
io_uring_setup chaqirig‘i orqali ring yaratilib, keyingi amallar paket (batch) ko‘rinishida yuboriladi.io_uring_enter chaqirig‘i yetarli, bu esa sistem chaqiruvlar sonini sezilarli darajada kamaytiradi.| 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) |
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);
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.