**epoll** là một Linux system call được sử dụng cho việc thông báo sự kiện trên các I/O (I/O event notification) và được giới thiệu lần đầu của phiên bản nhân Linux 2.5.44 để thay thế poll() system call trước đó với tính năng tương tự. epoll() giúp giám sát nhiều file descriptor của các I/O tương ứng để kiểm tra tính sẵn sàng của chúng. Trong các ứng dụng có số lượng lớn file descriptor cần giám sát, epoll có hiệu suất tốt hơn với độ phức tạp thuật toán là O(1) khi so với các system call tương tự trước đó có độ phức tạp thuật toán là O(n).)

epoll giống với kqueue của FreeBSD, với nhiều hàm ở tầng userspace, với mỗi hàm đều có một file descriptor, tương ứng với một kernel object (tạm dịch: đối tượng kernel), làm đối số. epoll dùng cấu trúc dữ liệu [red–black tree] (RB-tree) để theo dõi tất cả các file description mà nó được phân công.

API
---

Đối tượng của epoll API là epoll instance (tạm dịch đối tượng epoll), một cấu trúc dữ liệu ở phía kernel có thành phần chính gồm 2 list (tạm dịch: 2 danh sách):

* **Interest list** (đôi khi còn được gọi là epoll set): Nhóm các file descriptor được epoll đưa vào danh sách cần giám sát
* **Ready list**: Nhóm các file descriptor đã ở trạng thái ready (sẵn sàng) cho các thao tác I/O

Từ định nghĩa về 2 thành phần như trên, epoll hỗ trợ 3 API gồm `epoll_create()` và `epoll_create1()`, `epoll_ctl()` và `epoll_wait()`.

```
int epoll\_create(int size);
int epoll\_create1(int flags);

```

2 hàm `epoll_create1()` và `epoll_create()` có cùng tính năng khi đều khởi tạo một epoll instance. 2 hàm đều trả về một file descriptor, thường được đặt là `epfd`, tương ứng với epoll instance vừa khởi tạo đó. Đối số flag của hàm epoll\_create1() chỉ chấp nhận 1 giá trị hợp lệ duy nhất là EPOLL\_CLOEXEC. Hàm `epoll_create()` là 1 phiên bản cũ hơn của `epoll_create1()` và không được khuyến khích sử dụng kể từ Linux kernel version phiên bản 2.6.27 và glibc phiên bản 2.9.

```
int epoll\_ctl(int epfd, int op, int fd, struct epoll\_event \*event);

```

Hàm `epoll_ctl()` được dùng để thêm mới, chỉnh sửa hoặc xóa bỏ epoll instance (với file descriptor `epfd` tương ứng) trong interest list cùng với sự kiện epoll (`epoll_event`) tương ứng của file descriptor đó.

```
int epoll\_wait(int epfd, struct epoll\_event \*events, int maxevents, int timeout);

```

Hàm `epoll_wait` được dùng để chờ đợi sử kiện epoll trong 1 khoảng thời gian `timeout` (đơn vị mili giây) đã được ghi từ lần gọi hàm `epoll_ctl()` trước đó cho file descriptor epfd tương ứng. Nếu sự kiện epoll này xảy ra, `epoll_wait()` trả về số file descriptor đã sẵn sàng cho thao tác I/O, trả về `0` nếu không có file descriptor nào sẵn sàng trong thời gian `timeout`, và trả về `-1` nếu xảy ra lỗi.

Kích hoạt sự kiện epoll
-----------------------

epoll hỗ trợ cả 2 chế độ kích hoạt sự kiện là edge-triggered và level-triggered. Với edge-triggered, `epoll_wait` sẽ trả về giá trị >0 (ứng với số file descriptor đã sẵn sàng cho thao tác I/O) khi sự kiện epoll xảy ra được đưa vào hàng đợi (enqueued) của đối tượng epoll. Cờ **EPOLLET** được sử dụng cho edge-trigger. Với level-triggered mode, `epoll_wait` sẽ trả về giá trị >0 miễn là epoll event đó còn xảy ra.

Ví dụ với 1 pipe được giám sát với epoll sau khi nhận được data, `struct epoll_event *events` của `epoll_wait` sẽ được trả về với event tương ứng, cho biết rằng pipe đang có data để đọc. Giả sử rằng bên phía đọc pipe chỉ đọc 1 phần data trong pipe mà không đọc hết. Khi đó, ở chế độ level-triggered, những lần gọi`epoll_wait` tiếp theo sẽ đều trả về event để tiếp tục đọc, miễn là trong pipe vẫn còn data cho những lần đọc tiếp theo. Với chế độ edge-triggered, `epoll_wait` chỉ trả về 1 lần, tương ứng với sự kiện edge khi pipe chuyển từ "không có data" sang "có data".

Chỉ trích
---------

Bryan Cantrill chỉ ra rằng `epoll` có những lỗi mà lẽ ra có thể tránh được, nếu nó học từ các phần mềm/chương trình tiền nhiệm như input/output completion ports, event ports (Solaris) và kqueue. Tuy nhiên, phần lớn các chỉ trách của Cantrill đã được giải quyết bởi các option `EPOLLONESHOT` và `EPOLLEXCLUSIVE`. `EPOLLONESHOT` được thêm vào ở phiên bản 2.6.2 của Linux kernel mainline, xuất bản vào tháng 2 năm 2004. `EPOLLEXCLUSIVE` được thêm vào ở phiên bản 4.5, xuất bản vào tháng 3 2016.

Liên kết ngoài
--------------

* epoll manpage
* epoll patch

Chú thích
---------

1. 1 2 3 4  "epoll(7) - Linux manual page". Man7.org. ngày 17 tháng 4 năm 2012. Truy cập ngày 9 tháng 12 năm 2022.
2. ↑  Oleksiy Kovyrin (ngày 13 tháng 4 năm 2006). "Using epoll() For Asynchronous Network Programming". Kovyrin.net. Truy cập ngày 1 tháng 3 năm 2014.
3. ↑  "The Implementation of epoll (1)". *idndx.com*. Bản gốc lưu trữ ngày 10 tháng 8 năm 2017.
4. ↑  "epoll\_create1(2) - Linux manual page". Man7.org. Truy cập ngày 9 tháng 12 năm 2022.
5. ↑  Love, Robert (2013). *Linux System Programming*. O’Reilly. tr. 97, 98. ISBN 978-1-449-33953-1.
6. 1 2  "epoll\_ctl(2) - Linux manual page". Man7.org. Truy cập ngày 9 tháng 12 năm 2022.
7. ↑  "epoll\_wait(2) - Linux manual page". Man7.org. Truy cập ngày 9 tháng 12 năm 2022.
8. ↑  Archived at Ghostarchive and the Wayback Machine: "Ubuntu Slaughters Kittens | BSD Now 103". *YouTube*.
9. ↑  "Epoll is fundamentally broken 1/2". idea.popcount.org. ngày 20 tháng 2 năm 2017. Truy cập ngày 6 tháng 10 năm 2017.

| * x
* t
* s
Nhân Linux |
| --- |
| Tổ chức | 

|  |  |
| --- | --- |
| Nhân Linux | 
* Tổ chức Linux
* Linux Mark Institute
* Định luật Linus
* Tanenbaum–Torvalds debate
* Linux-libre
* Tux
* SCO and Linux
* Linaro
* GNU GPL v2
* menuconfig
* Supported computer architectures
* Kernel names
* Phê bình

 |
| Hỗ trợ | 
* Nhà phát triển
	+ *The Linux Programming Interface*
	+ kernel.org
	+ LKML
	+ Các hội nghị Linux
* Người dùng
	+ Linux User Group (LUG)

 |

 |
| Kĩ thuật | 

|  |  |
| --- | --- |
| Gỡ lỗi | 
* CRIU
* ftrace
* kdump
* Linux kernel oops
* SystemTap

 |
| Startup process | 
* vmlinux
* System.map
* dracut
* initrd
* initramfs

 |
| ABIs | 
* Linux Standard Base
* x32 ABI

 |
| APIs | 

|  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- |
| Tầng userspace | 

|  |  |
| --- | --- |
| FS, daemons | 
* devfs
* devpts
* debugfs
* procfs
* sysfs
* systemd
	+ udev
* Kmscon

 |
| Wrapper libraries | 
* C standard library
	+ glibc
	+ uClibc
	+ Bionic
		- libhybris
	+ dietlibc
	+ EGLIBC
	+ klibc
	+ musl
	+ Newlib
* libcgroup
* libdrm
* libalsa
* libevdev

 |

 |
| Một phần của nhân | 

|  |  |
| --- | --- |
| System Call Interface | 
* POSIX
	+ ioctl
	+ select
	+ open
	+ read
	+ close
	+ sync
	+ ...
* Chỉ của Linux
	+ futex
	+ epoll
	+ splice
	+ dnotify
	+ inotify
	+ readahead
	+ ...

 |
| In-kernel | 
* ALSA
* Crypto API
* DRM
* kernfs
* New API
* Video4Linux

 |

 |

 |
| Thành phần của nhân Linux | 
* Kernel modules
* BlueZ
* cgroups
* Console
* bcache
* Device mapper
* dm-cache
* dm-crypt
* DRM
* EDAC
* evdev
* Kernel same-page merging (KSM)
* LIO
* Framebuffer
* LVM
* KMS driver
* Netfilter
* Netlink
* nftables
* Network scheduler
* perf
* SLUB
* zram
* zswap

* Process and I/O schedulers:
* O(n) scheduler
* O(1) scheduler
* Completely Fair Scheduler (CFQ)
* Brain Fuck Scheduler
* Noop scheduler
* SCHED\_DEADLINE

* Security Modules: AppArmor
* Exec Shield
* grsecurity
	+ PaX
* seccomp
* SELinux
* Smack
* TOMOYO Linux
* Linux PAM

* Device drivers
	+ 802.11
	+ graphics
* Raw device

* initramfs
* KernelCare
* kexec
* kGraft
* kpatch
* Ksplice

 |
| Biến thể | 
* Mainline
	+ Linux kernel
* High-performance computing
	+ INK
	+ Compute Node Linux
	+ SLURM
* Real-time computing
	+ RTLinux
	+ RTAI
	+ Xenomai
	+ Carrier Grade Linux
* MMU-less
	+ μClinux
	+ PSXLinux
	+ DSLinux

|  |  |
| --- | --- |
| Virtualization | 
* Hypervisor
	+ KVM
	+ Xen
* OS-level virtualization
	+ Linux-VServer
	+ Lguest
	+ LXC
	+ OpenVZ
* Other
	+ L4Linux
	+ ELinOS
	+ User-mode Linux
	+ MkLinux
	+ coLinux

 |

 |

 |
| Sự tiếp nhận Linux | 

|  |  |
| --- | --- |
| Phạm vi sử dụng Linux | 
* Desktop
* Embedded
* Gaming
* Thin client:
	+ LTSP
	+ Thinstation
* Server:
	+ LAMP
	+ LYME/LYCE
* Devices

 |
| Người tiếp nhận | 
* List of Linux adopters
* GENIVI Alliance
* Proprietary software for Linux

 |

 |
| Nhân vật | 
* Jono Bacon
* Jonathan Corbet
* Alan Cox
* Jon "maddog" Hall
* Benjamin Mako Hill
* Michael Kerrisk
* Con Kolivas
* Greg Kroah-Hartman
* David S. Miller
* Ingo Molnár
* Andrew Morton
* Ian Murdock
* Bruce Perens
* Daniel Robbins
* Rusty Russell
* Linus Torvalds
* Theodore Ts'o

 |
| 
* Thể loại **Category**
* Trang Commons **Commons**
* Sách Wikipedia **Book**
* Trang Wikiversity **Wikiversity**
* Cổng thông tin **Portal**

 |