2013-07-13 35 views
6

Tôi đang viết một máy chủ TCP đồng thời có để xử lý nhiều kết nối với 'thread mỗi kết nối' phương pháp (sử dụng một bơi thread). Nghi ngờ của tôi là về cách nào là cách tối ưu nhất cho mỗi luồng để có được một bộ mô tả tập tin khác nhau.Calling accept() từ nhiều luồng

tôi thấy rằng trong hai phương pháp tiếp theo là khuyến cáo nhất:

  1. Một chủ đề chính rằng accepts() tất cả các kết nối đến và cửa hàng mô tả của họ trên một cấu trúc dữ liệu (ví dụ .: Phải có queue). Sau đó, mỗi thread có thể nhận được một fd từ hàng đợi.
  2. Chấp nhận() là được gọi trực tiếp từ mỗi chủ đề. (Đề xuất trong Unix Network Programming V1)

Vấn đề tôi tìm đến mỗi trong số họ:

  1. Cấu trúc dữ liệu tĩnh mà các cửa hàng tất cả các của fd phải khóa (mutex_lock) trước khi một sợi có thể đọc từ đó, vì vậy trong trường hợp một số lượng đáng kể các chủ đề muốn đọc trong chính xác cùng một lúc Tôi không biết bao nhiêu thời gian sẽ trôi qua cho đến khi tất cả chúng sẽ đạt được mục tiêu của chúng.
  2. Tôi đã đọc rằng vấn đề Thundering Herd liên quan đến các cuộc gọi đồng thời accept() chưa được giải quyết hoàn toàn trên Linux, vì vậy có thể tôi cần phải tạo một giải pháp nhân tạo . chậm như với cách tiếp cận 1.

Nguồn:

(một số liên kết nói về cách tiếp cận 2: does-the-thundering-herd-problem-exist-on-linux-anymore - và một bài viết tôi thấy abo ut nó (lỗi thời): linux-scalability/reports/accept.html

Và một câu trả lời SO rằng khuyến cáo phương pháp 1: can-i-call-accept-for-one-socket-from-several-threads-simultaneously


Tôi thực sự quan tâm về vấn đề này, vì vậy tôi sẽ đánh giá cao bất kỳ ý kiến ​​về điều đó :)

Trả lời

3

Như đã đề cập trong số StackOverflow answer bạn đã liên kết, một chuỗi gọi duy nhất chấp nhận() có thể là cách để thực hiện. Bạn đề cập đến những lo ngại về việc khóa, nhưng những ngày này bạn sẽ thấy việc triển khai hàng đợi lockfree có sẵn trong Boost.Lockfree, Intel TBB và các nơi khác. Bạn có thể sử dụng một trong số đó nếu bạn thích, nhưng bạn chỉ có thể sử dụng một biến điều kiện để cho các luồng công nhân của bạn ngủ và đánh thức một trong số chúng khi một kết nối mới được thiết lập.

+0

Cảm ơn ý tưởng về biến điều kiện, tôi nghĩ rằng nó có thể làm cho phương pháp tiếp cận khá hiệu quả. Dù sao tôi muốn biết nếu cách tiếp cận thứ hai có thể khả thi hay không (chỉ để xua tan một số nghi ngờ của tôi). (p.s.: Bởi thời điểm này tôi sẽ không chấp nhận câu trả lời của bạn vì tôi muốn nhận ý kiến ​​của người khác :)) – Str1101

+0

Cách tiếp cận thứ hai nên là de rigueur cho bất kỳ việc thực hiện hàng đợi nào bạn viết cho kịch bản này. Nếu bạn không sử dụng condvar bên trong hàng đợi, các khách hàng thread sẽ được giảm liên tục bỏ phiếu để xem liệu có dữ liệu nào khi bạn thực sự muốn cho họ ngủ cho đến khi có điều gì đó để làm tức là chặn khi không có gì trong hàng đợi đọc. – Duck