2016-01-05 11 views
5

Gần đây tôi đã bắt đầu viết một số mã C++ sử dụng ổ cắm, mà tôi muốn không đồng bộ. Tôi đã đọc nhiều bài viết về cách poll và select có thể được sử dụng để làm cho các socket của tôi không đồng bộ (sử dụng poll hoặc select để đợi một bộ đệm gửi hoặc recv), nhưng ở phía máy chủ của tôi, tôi có một mảng structffd, mỗi lần các ổ cắm nghe chấp nhận một kết nối, nó thêm nó vào mảng của struct pollfd để nó có thể theo dõi recv của socket đó (POLLIN).Có cách nào tốt hơn để sử dụng các cổng TCP không đồng bộ trong C++ thay vì thăm dò ý kiến ​​hoặc chọn không?

Vấn đề của tôi là nếu tôi có 5000 ổ cắm được kết nối với ổ cắm nghe trên máy chủ, thì mảng pollfd sẽ có kích thước 5000, vì nó sẽ giám sát tất cả các ổ cắm được kết nối NHƯNG cách duy nhất tôi biết để kiểm tra xem một recv cho một ổ cắm đã sẵn sàng chưa, là bằng cách lặp qua tất cả các mục trong mảng của struct pollfd để tìm những cái có revents bằng POLLIN. Điều này dường như không hiệu quả, khi số lượng các ổ cắm được kết nối bởi vì rất lớn. Có cách nào tốt hơn để làm điều này?

Cách tăng :: thư viện asio xử lý async_accept, async_send, v.v ...? Tôi nên xử lý nó như thế nào?

+0

Không có * tăng * trong [tag: c], hãy cẩn thận khi bạn chọn thẻ của mình. –

+4

Bạn đang trộn 'không chặn' và 'không đồng bộ'. Họ là những chế độ riêng biệt. 'select()' và bạn bè dành cho I/O không bị chặn. Có vẻ như bạn cần I/O không đồng bộ, trong trường hợp này bạn nên sử dụng 'boost', hoặc chuyển sang một ngôn ngữ khác như Java có tích hợp sẵn. Nhưng chỉ với 5000 khách hàng, bạn không nên bỏ qua việc chặn I/O với chủ đề. – EJP

+0

@EJP ... hoặc xem xét sử dụng ['std :: async()'] (http: //www.cplusplus.com/reference/future/async /) – Christophe

Trả lời

2

Cái quái gì, tôi sẽ tiếp tục và viết câu trả lời.

Tôi sẽ bỏ qua thuật ngữ "không đồng bộ" so với "không chặn" vì tôi tin rằng điều đó không liên quan đến câu hỏi của bạn.

Bạn đang lo lắng về hiệu suất khi xử lý hàng nghìn khách hàng mạng và bạn có quyền lo lắng. Bạn đã khám phá lại số C10K problem. Quay lại khi Web còn trẻ, mọi người đã thấy cần một số lượng nhỏ các máy chủ nhanh để xử lý một số lượng lớn các máy khách chậm (tương đối). Các giao diện kiểu chọn/thăm dò hiện có yêu cầu quét tuyến tính - trong cả vùng nhân và không gian người dùng - trên tất cả các socket để xác định xem đã sẵn sàng chưa. Nếu nhiều ổ cắm thường không hoạt động, máy chủ của bạn có thể mất nhiều thời gian hơn để tìm ra công việc cần làm hơn là thực hiện công việc thực tế.

nhanh về phía trước để ngày hôm nay, nơi chúng tôi có về cơ bản hai phương pháp để đối phó với vấn đề này:

1) Sử dụng một thread mỗi ổ cắm và chỉ vấn đề chặn đọc và viết. Điều này thường đơn giản nhất để viết mã, theo ý kiến ​​của tôi, và các hệ điều hành hiện đại là khá tốt trong việc cho phép các luồng nhàn rỗi ngủ một cách hòa bình ra khỏi đường mà không áp đặt bất kỳ chi phí hiệu năng đáng kể nào. Theo kinh nghiệm của tôi, cách tiếp cận này hoạt động rất tốt cho hàng trăm khách hàng; Cá nhân tôi không thể nói nó sẽ hoạt động như thế nào cho hàng ngàn người.

2) Sử dụng một trong các giao diện nền tảng cụ thể đã được giới thiệu để khắc phục sự cố C10K. Điều đó có nghĩa là epoll (Linux), kqueue (BSD/Mac), hoặc các cổng hoàn thành (Windows). (Nếu bạn nghĩ rằng epoll giống như poll, hãy xem lại.) Tất cả những điều này sẽ chỉ thông báo cho ứng dụng của bạn về các ổ cắm thực sự sẵn sàng, tránh quét tuyến tính lãng phí qua các kết nối không sử dụng. Có một số thư viện làm cho các giao diện nền tảng cụ thể này dễ sử dụng hơn, bao gồm libevent, libev và Boost.Asio. Bạn sẽ thấy rằng tất cả chúng cuối cùng gọi ra epoll trên Linux, kqueue trên BSD, và cứ thế, bất cứ khi nào các giao diện như vậy có sẵn.

+0

Về cơ bản chúng tôi có * ba * phương pháp tiếp cận: hai phương pháp bạn đề cập và I/O không đồng bộ. – EJP

+0

@EJP: Ở mức độ thấp, "I/O không đồng bộ" của bạn có khả năng được xây dựng trên một trong hai điều này. (Boost.Asio chắc chắn là, ví dụ.) Mặc dù có lẽ tôi không hiểu việc bạn sử dụng thuật ngữ này. Ngẫu nhiên, Wikipedia định nghĩa "I/O không đồng bộ" như một từ đồng nghĩa cho "I/O không chặn I" (https://en.wikipedia.org/wiki/Asynchronous_I/O), và sau đó tiếp tục đưa ra mô tả có không có gì để làm với câu hỏi này hoặc câu trả lời của tôi. – Nemo

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