2010-08-04 24 views
6

Tôi đã tạo một ứng dụng thực hiện công việc trên hàng nghìn tệp, sau đó viết các bản sao đã sửa đổi của các tệp này vào đĩa. Tôi đang sử dụng một ThreadPool nhưng nó đã được sinh ra rất nhiều chủ đề pc đã trở thành không phản hồi 260 tổng số), vì vậy tôi thay đổi tối đa từ mặc định của 250 xuống 50, điều này giải quyết vấn đề (ứng dụng chỉ đẻ khoảng 60 chủ đề tổng số), tuy nhiên bây giờ các tập tin đang trở nên sẵn sàng một cách nhanh chóng, nó buộc lên giao diện người dùng đến điểm mà máy tính không phản hồi.Tôi có thể giới hạn I/O của ứng dụng C#

Có cách nào giới hạn số lượng I/O - ý tôi là, tôi thích sử dụng 50 chủ đề để thực hiện công việc trên các tệp chứ không phải 50 chủ đề viết cùng một lúc khi chúng được xử lý. Tôi không muốn kiến ​​trúc sư viết lại phần của tập tin nếu tôi có thể giữ nó - tôi đã hy vọng tôi có thể giới hạn số lượng I/O (đồng thời) các chủ đề từ hồ bơi này có thể tiêu thụ.

+1

Bạn nói "các tệp đang trở nên sẵn sàng quá nhanh, kết nối với giao diện người dùng". Giao diện người dùng có được cập nhật mỗi lần tệp sẵn sàng không? Nếu có, đó có phải là vấn đề thực sự ở đây không ?? –

Trả lời

4

Bạn thực sự không cần quá nhiều chủ đề. Một đĩa chỉ có thể hỗ trợ thông lượng đọc và ghi tối đa của nó, mà một sợi đơn có thể dễ dàng tối đa nếu nó được dành riêng cho IO nghĩa là đọc hoặc viết. Bạn cũng không thể đọc và ghi vào đĩa cứng cùng một lúc (mặc dù điều này phức tạp với các lớp bộ nhớ đệm của hệ điều hành, vv), vì vậy việc đọc và ghi các luồng đồng thời có thể rất phản tác dụng. Ngoài ra còn có ít được thu được từ việc có nhiều chủ đề hơn các bộ xử lý \ lõi cho các nhiệm vụ không phải của bạn vì bất kỳ chủ đề bổ sung nào cũng sẽ dành nhiều thời gian chờ đợi một lõi để có sẵn, ví dụ: nếu bạn có 50 luồng và 4 lõi, tối thiểu 46 luồng sẽ không hoạt động tại bất kỳ thời điểm nào. Các chủ đề lãng phí sẽ góp phần vào việc tiêu thụ bộ nhớ cũng phải chịu chi phí thực hiện vì tất cả chúng sẽ chiến đấu để có được một vết nứt tại một thời điểm trên lõi, và hệ điều hành phải phân xử cuộc chiến này.

Một cách tiếp cận đơn giản hơn sẽ có một chuỗi duy nhất có công việc để đọc trong tệp và sau đó thêm dữ liệu vào hàng đợi chặn (ví dụ: xem ConcurrentQueue), trong khi đó có một số chuỗi công việc đang đợi tập tin dữ liệu trong hàng đợi (ví dụ như một số chủ đề bằng số lượng bộ vi xử lý \ lõi). Các luồng công nhân này sẽ nhai theo hàng đợi khi các mục được thêm vào và chặn khi nó trống. Khi một chuỗi công nhân kết thúc một phần công việc, nó có thể thêm vào một hàng đợi chặn khác đang được giám sát bởi chủ đề đọc hoặc một luồng ghi chuyên dụng. Công việc của nó là viết các tệp ra.

Mẫu này tìm cách cân bằng IO và CPU giữa các chuỗi chủ đề hợp tác nhỏ hơn nhiều, trong đó số lượng các chuỗi IO bị giới hạn đối với những gì có khả năng vật lý của ổ cứng và một số chuỗi công nhân CPU hợp lý cho số lượng bộ xử lý \ lõi bạn có. Về bản chất nó tách IO và CPU làm việc để mọi thứ hoạt động tốt hơn dự đoán. Hơn nữa, nếu IO thực sự là vấn đề (và không phải là một số lượng lớn của tất cả các chủ đề chiến đấu với nhau), sau đó bạn có thể đặt một số tạm dừng (ví dụ Thread.Sleep) trong tập tin của bạn đọc và viết đề để giới hạn như thế nào nhiều công việc họ làm.

Cập nhật

Có lẽ nó là giá trị giải thích lý do tại sao có rất nhiều chủ đề được tạo ra ở nơi đầu tiên. Đây là một trường hợp thoái hóa để sử dụng threadpool, và được tập trung xung quanh việc xếp hàng các workitem có một thành phần của IO trong chúng.

Trình tạo luồng thực hiện các mục công việc từ hàng đợi của nó và theo dõi thời gian thực hiện các mục công việc đang thực hiện. Nếu hiện tại việc thực thi workitem mất nhiều thời gian để hoàn thành (tôi nghĩ nửa giây từ bộ nhớ) thì nó sẽ bắt đầu thêm nhiều luồng hơn vào nhóm vì nó tin rằng hàng đợi sẽ xử lý nhanh hơn \ khá công bằng. Tuy nhiên, nếu các workitem đồng thời bổ sung cũng đang thực hiện công việc IO đối với đĩa được chia sẻ, thì hiệu suất của đĩa sẽ thực sự giảm, nghĩa là workitems sẽ mất nhiều thời gian hơn để thực thi. Bởi vì workitems mất nhiều thời gian để thực thi, threadpool thêm nhiều chủ đề hơn. Đây là trường hợp thoái hóa, nơi mà hiệu suất trở nên tồi tệ hơn và tồi tệ hơn khi nhiều chủ đề được thêm vào.

Việc sử dụng semaphore như được đề xuất sẽ phải được thực hiện cẩn thận, vì semaphore có thể gây chặn luồng threadpool, threadpool sẽ thấy workitems mất một thời gian dài để thực thi, và nó vẫn sẽ bắt đầu thêm nhiều chủ đề.

+0

ThreadPool thực hiện tính toán phức tạp dựa trên nội dung của mỗi tệp và sử dụng ThreadPool đã thúc đẩy phần này của quá trình lên LOTS :-) – schmoopy

+0

@schmoopy Tôi không chắc tôi hiểu nhận xét của bạn. Tôi quen thuộc với threadpool và xử lý tệp, do đó tôi đã trả lời câu hỏi của bạn. Cụ thể tôi có thể thêm ... –

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