2009-03-13 31 views
6

chọn() được định nghĩa là:Query trên Chọn hệ thống Gọi

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

NFDS đại diện cho mô tả tập tin cao nhất trong tất cả các bộ trao cộng thêm một. Tôi muốn biết tại sao dữ liệu này được yêu cầu cho select() khi thông tin fd_set có sẵn.

Nếu FD trong tập hợp là, 4, 8, 9, giá trị nfds sẽ là 10. Chọn() moniter fds 9,8,7,6,5,4?

Trả lời

8

Bắt là fd_set không thực sự là "bộ" theo cách bạn đang nghĩ. Chi tiết đằng sau hậu trường là việc thực hiện một fd_set chỉ là một số nguyên được sử dụng như một bitfield. Nói cách khác, thực hiện

fd_set foo; 
FD_CLEAR(&foo); 
FD_SET(&foo, 3); 

Đặt foo thành giá trị thập phân 8 - nó đặt bit thứ tư-ít nhất là 1 (nhớ rằng 0 là bộ mô tả hợp lệ).

FD_SET(&foo, 3); 

tương đương với

foo |= (1 << 3); 

Vì vậy, để cho chọn để làm việc đúng, nó cần phải biết rằng những bit của fd_set là bit mà bạn quan tâm. Nếu không thì sẽ không có cách nào để nó cho biết một bit không có nghĩa là "trong" tập hợp nhưng được đặt thành false từ bit không có nghĩa là "không nằm trong" tập hợp.

Trong ví dụ của bạn, tập fd_set có 4, 8 và 9 và n = 10 được hiểu là "Tập hợp có 10 mục nhập (fds 0-9). Mục nhập 4, 8 và 9 là đúng (theo dõi chúng Các mục nhập 1,2,3,5,6,7 là sai (không giám sát chúng). Bất kỳ giá trị fd nào lớn hơn 9 chỉ đơn giản là không có trong khoảng thời gian đã định. "

+1

Nhưng số lượng bit trong int là 32, nhưng làm cách nào để theo dõi bất kỳ fd nào có giá trị lớn hơn 31 – Poorna

+0

ai đó có thể trả lời nhận xét này? – euphoria83

+0

@Shishir: Posix định nghĩa 'fd_set' là cấu trúc. Các nội bộ được thực hiện xác định, nhưng một thực hiện phổ biến là cho các cấu trúc để chứa một mảng của longs với đủ bit trong mảng để trang trải tất cả các fd có thể. Điều này làm việc vì Posix cũng yêu cầu 'mở' để trả về" bộ mô tả tệp không được sử dụng số thấp nhất ". Vì vậy, bạn sẽ không vượt quá phạm vi của mảng trừ khi bạn có FD_SETSIZE tệp đang mở. http://pubs.opengroup.org/onlinepubs/007904975/basedefs/sys/select.h.html – indiv

0

Chọn giám sát các FD mà bạn đã bật bằng macro FD_SET. Nếu bạn không kích hoạt bất kỳ FD nào để theo dõi, hãy chọn() không theo dõi bất kỳ.

"NFDS" chắc chắn là không cần thiết, nhưng nó là một phần của giao diện lựa chọn(), vì vậy bạn cần phải sử dụng nó :)

Dù sao, nếu bạn có {4, 8, 9} trong tập, bạn đặt nfds thành 10 (như bạn đã đề cập), và select() sẽ chỉ giám sát ba FDs 4, 8 và 9.

0

Đây có thể là một tối ưu hóa để select không phải đi qua toàn bộ fd_set để tìm mô tả nào thực sự được sử dụng. Nếu không có tham số đó, select sẽ luôn luôn cần phải xem xét toàn bộ tập hợp để tìm mô tả nào thực sự được sử dụng trong cuộc gọi, với tham số, một số công việc đó có thể được bỏ qua.

Các vấn đề liên quan