Mục đích của đối số đầu tiên để chọn cuộc gọi hệ thống là gì?


25

Từ man select

int select(int nfds, fd_set *readfds, fd_set *writefds,
           fd_set *exceptfds, struct timeval *timeout);

nfds là bộ mô tả tệp được đánh số cao nhất trong bất kỳ bộ nào trong ba bộ, cộng với 1.

Mục đích của nfds, khi chúng ta đã có readfds, writefdsexceptfds, từ đó các mô tả tập tin có thể được xác định là gì?


Tôi đã định hỏi về SO, nhưng nó tập trung hơn ở đây và các lệnh gọi API C được coi là theo chủ đề .
phunehehe

Câu trả lời:


25

Trong "Lập trình nâng cao trong môi trường UNIX" , W. Richard Stevens nói rằng đó là một tối ưu hóa hiệu suất:

Bằng cách chỉ định bộ mô tả cao nhất mà chúng tôi quan tâm, hạt nhân có thể tránh được hàng trăm bit không sử dụng trong ba bộ mô tả, tìm kiếm các bit được bật.

(Ấn bản 1, trang 399)

Nếu bạn đang thực hiện bất kỳ loại lập trình hệ thống UNIX nào, sách APUE rất được khuyến khích.


CẬP NHẬT

An fd_setthường có thể theo dõi tới 1024 bộ mô tả tệp.

Cách hiệu quả nhất để theo dõi cái nào fdsđược đặt 0và được đặt thành 1sẽ là một bitet, vì vậy mỗi cái fd_setsẽ bao gồm 1024 bit.

Trên hệ thống 32 bit, một int dài (hoặc "từ") là 32 bit, do đó, có nghĩa là mỗi bit fd_set
1024/32 = 32 từ.

Nếu nfdslà một cái gì đó nhỏ, chẳng hạn như 8 hoặc 16, có trong nhiều ứng dụng, nó chỉ cần nhìn vào từ thứ 1, rõ ràng sẽ nhanh hơn so với nhìn vào bên trong tất cả 32.

(Xem FD_SETSIZE__NFDBITStừ /usr/include/sys/select.hcác giá trị trên nền tảng của bạn.)


CẬP NHẬT 2

Tại sao chữ ký hàm không

int select(fd_set *readfds, int nreadfds,
           fd_set *writefds, int nwritefds,
           fd_set *exceptfds, int nexceptfds,
           struct timeval *timeout);

Tôi đoán là bởi vì mã cố gắng giữ tất cả các đối số trong các thanh ghi , vì vậy CPU có thể hoạt động trên chúng nhanh hơn và nếu nó phải theo dõi thêm 2 biến, CPU có thể không có đủ các thanh ghi.

Vì vậy, nói cách khác, selectđang phơi bày một chi tiết thực hiện để nó có thể nhanh hơn.


2
Điều đó, hoặc gần đây hơn Giao diện lập trình Linux
chris

APUE cũng được cập nhật gần đây. Ấn bản thứ hai: amazon.com/gp/aw/d.html/ref=aw_d_detail?pd=1&a=0201433079
Mikel

@chris Tôi sẽ kiểm tra Giao diện lập trình Linux. Cảm ơn.
Mikel

Cảm ơn thông tin, tôi sẽ kiểm tra các cuốn sách khi tôi dành thời gian.
phunehehe

APUE 2nd Ed: 27 tháng 6 năm 2005 (bao gồm linux-2.4.22) TLPI: Tháng 10 năm 2010 (bao gồm linux-2.6,35)
chris

6

Tôi không biết chắc chắn, vì tôi không phải là một trong những nhà thiết kế của select (), nhưng tôi nói đó là tối ưu hóa hiệu suất. Hàm gọi biết có bao nhiêu phần mô tả tệp được đặt trong phần đọc, ghi và ngoại trừ FD, vậy tại sao kernel lại tìm ra nó?

Hãy nhớ rằng vào đầu những năm 80, khi select () được giới thiệu, họ không có bộ xử lý đa gigaghertz, đa bộ xử lý. VAX 25 MHz khá nhanh. Thêm vào đó, bạn muốn select () hoạt động nhanh nếu có thể: nếu một số I / O đang chờ quá trình, tại sao làm cho quá trình chờ?


Đối với lập luận của bạn, tôi sẽ nói rằng chúng ta cần nreadfds, nwritefdsnexceptfdsthay vì chỉ một nfds.
phunehehe

Có lẽ vì vậy mà nfdscó thể đi vào một đăng ký để truy cập nhanh hơn. Nếu nó phải theo dõi ba số, cùng với tất cả các đối số khác, có thể CPU sẽ không có đủ các thanh ghi. Tất nhiên, kernel có thể tự tạo nfdsdựa trên 3 biến giả định của bạn. Vì vậy, dự đoán của tôi là nó phơi bày một chi tiết thực hiện để đạt được hiệu quả.
Mikel

@Mikel, phunehehe: Các nfdsđối số riêng biệt sẽ mang lại rất ít lợi ích. Hầu hết thời gian, quy trình đã mở rất ít quy trình liên quan đến FD_SETSIZE. Một trường hợp điển hình có thể có (4,4,2) trong số 1024; thực hiện kiểm tra kernel (4,4,4) là một chiến thắng lớn so với (1024,1024,1024), nhưng tối ưu hóa xuống (4,4,2) sẽ gần như vô dụng.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles: mức tăng sẽ là một API sạch hơn. (Như vậy, hoặc là lập trình viên phải thực hiện thêm công việc để tính toán nfds, hoặc lười biếng và gọi select(FD_SETSIZE, ...), việc này sẽ chậm hơn.)
Mikel

OTOH, chỉ theo dõi một biến tối đa có thể dễ dàng hơn cho lập trình viên.
Mikel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.