Đối với số lượng rất nhỏ các ổ cắm (tất nhiên là thay đổi tùy thuộc vào phần cứng của bạn, nhưng chúng ta đang nói về thứ gì đó theo thứ tự 10 hoặc ít hơn), select có thể đánh bại kỷ nguyên sử dụng bộ nhớ và tốc độ thời gian chạy. Tất nhiên, đối với số lượng ổ cắm nhỏ như vậy, cả hai cơ chế đều nhanh đến mức bạn không thực sự quan tâm đến sự khác biệt này trong đại đa số trường hợp.
Tuy nhiên, một sự làm rõ. Cả select và epoll đều chia tỷ lệ tuyến tính. Tuy nhiên, một sự khác biệt lớn là các API hướng tới không gian người dùng có sự phức tạp dựa trên những thứ khác nhau. Chi phí của một select
cuộc gọi tương đương với giá trị của bộ mô tả tệp được đánh số cao nhất mà bạn chuyển nó. Nếu bạn chọn trên một fd duy nhất, 100, thì chi phí đó đắt gấp đôi so với chọn trên một fd duy nhất, 50. Thêm nhiều fd dưới mức cao nhất không hoàn toàn miễn phí, vì vậy nó phức tạp hơn một chút so với thực tế, nhưng điều này là một ước lượng đầu tiên tốt cho hầu hết các triển khai.
Chi phí của epoll gần với số lượng bộ mô tả tệp thực sự có các sự kiện trên chúng. Nếu bạn đang theo dõi 200 bộ mô tả tệp, nhưng chỉ 100 trong số chúng có các sự kiện trên đó, thì bạn (rất gần) chỉ trả tiền cho 100 bộ mô tả tệp đang hoạt động đó. Đây là lúc epoll có xu hướng cung cấp một trong những lợi thế chính của nó so với lựa chọn. Nếu bạn có một nghìn khách hàng chủ yếu là nhàn rỗi, thì khi bạn sử dụng select, bạn vẫn phải trả cho tất cả một nghìn khách hàng trong số họ. Tuy nhiên, với epoll, giống như bạn chỉ có một số ít - bạn chỉ trả tiền cho những cái đang hoạt động tại bất kỳ thời điểm nào.
Tất cả điều này có nghĩa là epoll sẽ dẫn đến việc sử dụng CPU ít hơn cho hầu hết các khối lượng công việc. Về mức độ sử dụng bộ nhớ, nó có một chút rắc rối. select
quản lý để đại diện cho tất cả các thông tin cần thiết theo cách rất nhỏ gọn (một bit cho mỗi bộ mô tả tệp). Và giới hạn FD_SETSIZE (thường là 1024) về số lượng bộ mô tả tệp bạn có thể sử dụng có select
nghĩa là bạn sẽ không bao giờ chi tiêu nhiều hơn 128 byte cho mỗi bộ ba fd mà bạn có thể sử dụngselect
(đọc, ghi, ngoại lệ). So với 384 byte tối đa đó, epoll giống như một con lợn. Mỗi bộ mô tả tệp được biểu diễn bằng cấu trúc nhiều byte. Tuy nhiên, về mặt tuyệt đối, nó vẫn sẽ không sử dụng nhiều bộ nhớ. Bạn có thể đại diện cho một số lượng lớn các bộ mô tả tệp trong vài chục kilobyte (tôi nghĩ rằng khoảng 20k cho mỗi 1000 bộ mô tả tệp). Và bạn cũng có thể thực tế là bạn phải dành tất cả 384 byte trong số đó select
nếu bạn chỉ muốn theo dõi một bộ mô tả tệp nhưng giá trị của nó xảy ra là 1024, khi có epoll thì bạn chỉ tốn 20 byte. Tuy nhiên, tất cả những con số này đều khá nhỏ, vì vậy nó không tạo ra nhiều sự khác biệt.
Và cũng có lợi ích khác của epoll, mà có lẽ bạn đã biết, rằng nó không giới hạn ở các bộ mô tả tệp FD_SETSIZE. Bạn có thể sử dụng nó để theo dõi bao nhiêu bộ mô tả tệp mà bạn có. Và nếu bạn chỉ có một bộ mô tả tệp, nhưng giá trị của nó lớn hơn FD_SETSIZE, epoll cũng hoạt động với điều đó, nhưng select
không.
Ngẫu nhiên, gần đây tôi cũng đã phát hiện ra một nhược điểm nhỏ epoll
so với select
hoặc poll
. Mặc dù không có API nào trong số ba API này hỗ trợ tệp bình thường (tức là tệp trên hệ thống tệp) select
và poll
thể hiện sự thiếu hỗ trợ này khi báo cáo các bộ mô tả luôn có thể đọc được và luôn có thể ghi. Điều này làm cho chúng không phù hợp với bất kỳ loại I / O hệ thống tệp không chặn có ý nghĩa nào, một chương trình sử dụng select
hoặc poll
và tình cờ gặp phải bộ mô tả tệp từ hệ thống tệp ít nhất sẽ tiếp tục hoạt động (hoặc nếu nó không thành công, nó sẽ không phải là do của select
hoặc poll
), mặc dù nó có lẽ không phải với hiệu suất tốt nhất.
Mặt khác, epoll
sẽ nhanh chóng thất bại với một lỗi ( EPERM
dường như) khi được yêu cầu giám sát một bộ mô tả tệp như vậy. Nói một cách chính xác, điều này hầu như không chính xác. Nó chỉ đơn thuần báo hiệu sự thiếu hỗ trợ của nó một cách rõ ràng. Thông thường tôi sẽ hoan nghênh các điều kiện lỗi rõ ràng, nhưng điều này không có tài liệu (theo như tôi có thể nói) và dẫn đến một ứng dụng bị hỏng hoàn toàn, thay vì chỉ hoạt động với hiệu suất có khả năng bị suy giảm.
Trong thực tế, nơi duy nhất tôi thấy điều này xuất hiện là khi tương tác với stdio. Người dùng có thể chuyển hướng stdin hoặc stdout từ / đến một tệp bình thường. Trong khi trước đây stdin và stdout sẽ là một đường ống - được epoll hỗ trợ tốt - sau đó nó trở thành một tệp bình thường và epoll bị lỗi lớn, phá vỡ ứng dụng.
poll
cho đầy đủ?