2013-02-01 25 views
6

Tình trạng của tôi là:Nhiều nhà văn, một người đọc, bộ sưu tập

Nhiều chủ đề phải viết đồng thời vào cùng bộ sưu tập (thêm và thêm). Thứ tự của các mục không phải là một vấn đề. Khi tất cả các chủ đề đã hoàn thành (tham gia) và im trở lại chủ đề chính của tôi, sau đó tôi cần phải đọc tất cả các dữ liệu thu thập nhanh trong một phong cách foreach, nơi không có khóa thực tế là cần thiết vì tất cả các chủ đề được thực hiện.

Trong "ngày cũ", tôi có thể sử dụng khóa trình viết cho điều này trên Danh sách, nhưng với bộ sưu tập đồng thời mới, tôi tự hỏi không có lựa chọn nào tốt hơn. Tôi chỉ không thể tìm ra đó là hầu hết các bộ sưu tập đồng thời dường như giả định rằng người đọc cũng trên một chủ đề đồng thời.

+0

nếu bạn đang sử dụng .Net 4.0 trở lên. ConcurrentBag sẽ giải quyết mục đích của bạn. Tôi nghĩ rằng tốt nhất nếu bạn không quan tâm đến trật tự và loại bỏ các yếu tố. –

+0

Tôi đã nhìn vào nó, nhưng sẽ không một foreach trên một concurrentbag ngụ ý một hình phạt khóa cho mỗi lần đọc? Làm cho khóa độc giả cũ trở nên hiệu quả hơn? –

+0

@Hans và Philip Rieck, bạn hoàn toàn đúng. Không có lý do gì để sử dụng một bộ sưu tập đồng thời ở đây. Rõ ràng với tôi bây giờ, tôi đã bị mù và hoang tưởng bởi thực tế rằng tôi đã phải quay lên rất nhiều chủ đề. Thx để làm rõ :). –

Trả lời

5

Thứ tự của các mục không phải là vấn đề. Khi tất cả các chủ đề đã hoàn thành (tham gia) và im trở lại chủ đề chính của tôi, sau đó tôi cần đọc tất cả các dữ liệu đã thu thập

Bạn chưa nêu yêu cầu về bộ sưu tập an toàn chỉ. Không có điểm nào trong việc chia sẻ một bộ sưu tập duy nhất vì bạn không bao giờ đọc cùng một lúc bạn viết. Cũng không quan trọng là tất cả các văn bản đều xảy ra với cùng một bộ sưu tập vì trật tự không quan trọng. Cũng không nên quan trọng vì trật tự sẽ là ngẫu nhiên.

Vì vậy, chỉ cần cung cấp cho mỗi chuỗi bộ sưu tập của riêng nó để lấp đầy, không cần khóa. Và lặp lại chúng từng cái một, không cần khóa.

4

Hãy thử System.Collections.Concurrent.ConcurrentBag.

Từ mô tả của bộ sưu tập:

Đại diện cho một, bộ sưu tập có thứ tự thread-safe của các đối tượng.

Tôi tin rằng điều này đáp ứng tiêu chí xử lý nhiều chủ đề và thứ tự của các mục không quan trọng, và sau này khi bạn quay trở lại chủ đề chính, bạn có thể nhanh chóng tìm hiểu về bộ sưu tập và hành động trên từng mục.

+0

Tôi đã nhìn vào nó nhưng sẽ không cho phép trên một concurrentbag ngụ ý một hình phạt khóa cho mỗi lần đọc? Làm cho khóa độc giả cũ trở nên hiệu quả hơn? –

+0

@ChristianMikkelsen Bạn đang chạy .NET 4.0 hoặc .NET 4.5? Mục nhập blog sau đây thảo luận về hiệu suất 'ConcurrentBag': http://ayende.com/blog/156097/the-high-cost-of-concurrentbag-in-net-4-0 –

+2

@ChristianMikkelsen không có bạn nên ổn: ConcurrentBag. GetEnumerator() trả về một ảnh chụp tại thời điểm đó để nó sẽ không khóa bộ sưu tập. Xem: http://msdn.microsoft.com/en-us/library/dd381960.aspx – drch

6

Tôi không tin rằng bạn muốn sử dụng bất kỳ bộ sưu tập nào trong số System.Collections.Concurrent. Những thường có thêm chi phí để cho phép đọc đồng thời.

Trừ khi bạn có nhiều tranh chấp, có lẽ bạn nên lấy khóa đơn giản List<T> và thêm vào đó. Bạn sẽ có một số lượng nhỏ trên không khi Danh sách thay đổi kích thước, nhưng nó sẽ là khá thường xuyên.

Tuy nhiên, những gì tôi có lẽ sẽ làm gì trong trường hợp này chỉ đơn giản là thêm vào một List<T>mỗi thread chứ không phải là chia sẻ một, và một trong hai hợp nhất chúng vào cuối chế biến, hoặc đơn giản là lặp qua tất cả các yếu tố trong mỗi bộ sưu tập.

Bạn có thể sử dụng ConcurrentBag và sau đó gọi .ToArray() hoặc GetEnumerator() trên đó khi sẵn sàng đọc (bỏ qua hình phạt cho mỗi lần đọc), nhưng bạn sẽ thấy tốc độ chèn chậm hơn một chút so với khóa ghi thủ công của bạn trên một đơn giản List. Nó thực sự phụ thuộc vào số lượng tranh chấp. Các ConcurrentBag là khá tốt về phân vùng, nhưng như bạn lưu ý, được hướng đến đồng thời đọc viết.

Như thường lệ, hãy đánh giá tình huống cụ thể của bạn! Hiệu suất đa luồng phụ thuộc nhiều vào nhiều thứ trong cách sử dụng thực tế và những thứ như kiểu dữ liệu, số lần chèn, và như vậy sẽ thay đổi kết quả đáng kể - một số thực tế đáng giá một gallon lý thuyết.

+0

+1 để được đề xuất về điểm chuẩn. Philip là đúng, bạn thực sự muốn biết làm thế nào dữ liệu thực tế của bạn/đọc/ghi cư xử. –

+1

+1 cho một Danh sách cho mỗi chủ đề. – dtb

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