2012-10-07 39 views
5

Tôi đang viết một máy chủ trong Linux sẽ phải hỗ trợ các hoạt động đọc/ghi đồng thời từ nhiều máy khách. Tôi muốn sử dụng chức năng chọn để quản lý tính khả dụng của tính năng đọc/ghi.Lợi ích của việc sử dụng ổ cắm không chặn với chức năng "chọn" là gì?

Điều tôi không hiểu là: Giả sử tôi muốn đợi cho đến khi ổ cắm có sẵn dữ liệu để đọc. Tài liệu dành cho chọn tuyên bố rằng nó chặn cho đến khi có sẵn dữ liệu để đọc và chức năng đọc sẽ không chặn.

Vì vậy, nếu tôi đang sử dụng lựa chọn và tôi biết rằng chức năng đọc sẽ không chặn, tại sao tôi cần phải đặt các ổ cắm của mình thành không bị chặn?

Trả lời

6

Có thể có trường hợp khi ổ cắm được báo cáo là đã sẵn sàng nhưng vào thời điểm bạn kiểm tra, nó sẽ thay đổi trạng thái của nó.

Một trong những ví dụ tốt là chấp nhận kết nối. Khi một kết nối mới đến, một ổ cắm nghe được báo cáo là đã sẵn sàng để đọc. Vào thời điểm bạn nhận được cuộc gọi chấp nhận, kết nối có thể bị đóng bởi phía bên kia trước khi gửi bất kỳ thứ gì và trước khi chúng tôi gọi là accept. Tất nhiên, việc xử lý trường hợp này phụ thuộc vào hệ điều hành, nhưng có thể là accept sẽ đơn giản chặn cho đến khi kết nối mới được thiết lập, điều này sẽ khiến ứng dụng của chúng tôi phải chờ một khoảng thời gian không hạn chế để xử lý các ổ cắm khác. Nếu ổ cắm nghe của bạn ở chế độ không chặn, điều này sẽ không xảy ra và bạn sẽ nhận được EWOULDBLOCK hoặc một số lỗi khác, nhưng accept sẽ không chặn bất kỳ cách nào.

Một số hạt nhân đã từng có (tôi hy vọng nó đã được khắc phục ngay) một lỗi thú vị với UDP và select. Khi một datagram đến select, hãy thức dậy với socket với datagram được đánh dấu là đã sẵn sàng để đọc. Việc xác nhận kiểm tra datagram được hoãn lại cho đến khi mã người dùng gọi recvfrom (hoặc một số API khác có khả năng nhận các gói dữ liệu UDP). Khi mã gọi recvfrom và mã xác nhận phát hiện một sự kiểm tra không khớp, một datagram chỉ đơn giản là bị bỏ và recvfrom kết thúc bị chặn cho đến khi một datagram tiếp theo đến. Một trong các bản vá lỗi khắc phục sự cố này (cùng với mô tả sự cố) có thể được tìm thấy here.

2

Một trong những lợi ích, là nó sẽ bắt bất kỳ lỗi lập trình nào bạn thực hiện, bởi vì nếu bạn cố gắng đọc một ổ cắm thường chặn bạn, bạn sẽ nhận được EWOULDBLOCK. Đối với các đối tượng không phải là ổ cắm, hành vi api chính xác có thể thay đổi, xem http://www.scottklement.com/rpg/socktut/nonblocking.html.

+0

Aha, nhờ cho điều đó. :) – CaptainCodeman

1

Điều này nghe có vẻ khó hiểu nhưng không phải vậy. Lý do tốt nhất để khiến họ không chặn là vì vậy bạn không chặn.

Hãy nghĩ về điều đó. select() cho bạn biết có gì đó để đọc nhưng bạn không biết bao nhiêu. Có thể là 2 byte, có thể là 2.000. Trong hầu hết các trường hợp, việc rút hết dữ liệu là có hiệu quả hơn trước khi quay trở lại select. Vì vậy, bạn nhập một vòng lặp while để đọc

while (1) 
{ 
    n = read(sock, buffer, 200); 
    //check return code, etc 
} 

Điều gì xảy ra khi đọc lần cuối khi không còn gì để đọc? Nếu ổ cắm không chặn, bạn sẽ chặn, do đó đánh bại (ít nhất một phần) điểm của select().

3

Khác với lỗi hạt nhân được người khác đề cập, lý do khác để chọn ổ cắm không chặn, ngay cả với vòng lặp bỏ phiếu, là nó cho phép hiệu suất cao hơn với dữ liệu đến nhanh. Hãy suy nghĩ điều gì sẽ xảy ra khi một ổ cắm chặn được đánh dấu là "có thể đọc được". Bạn không có ý tưởng bao nhiêu dữ liệu đã đến, vì vậy bạn có thể đọc nó một cách an toàn một lần.Sau đó, bạn phải quay trở lại vòng lặp sự kiện để poller của bạn kiểm tra xem ổ cắm vẫn có thể đọc được hay không. Điều này có nghĩa rằng cứ mỗi đọc đơn từ hay ghi vào ổ cắm bạn phải làm hai ít nhất hai hệ thống gọi: các select để cho bạn biết nó an toàn để đọc, và đọc/ghi gọi chính nó.

Với ổ cắm non-blocking bạn có thể bỏ qua các cuộc gọi không cần thiết để select sau khi người đầu tiên. Khi một ổ cắm được gắn cờ là có thể đọc được bởi select, bạn có thể chọn đọc từ nó miễn là nó trả về dữ liệu, cho phép xử lý nhanh hơn của vụ nổ nhanh chóng của dữ liệu.

+0

Cảm ơn, điểm rất tốt, tôi không biết rằng cố gắng đọc sẽ nhanh hơn lựa chọn khác. – CaptainCodeman

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