2010-03-02 37 views
5

tôi đang cố gắng để đơn giản hóa vấn đề như sau,C# luồng vấn đề

  1. tôi có khoảng 100 file mà tôi muốn đọc và sau đó xử lý dữ liệu
  2. Ví mà tôi duy trì mảng của tên tập tin và vị trí
  3. Tôi sinh ra các luồng để thực hiện công việc đọc tệp.

Bây giờ vấn đề của tôi là tôi muốn đảm bảo rằng chỉ có 5 chủ đề được sinh ra tại một thời điểm khi bắt đầu 100 + chủ đề không phải là ý tưởng tốt cả. Vì vậy, xin vui lòng cho tôi biết cách tiếp cận tôi nên sử dụng để đảm bảo rằng chỉ có 5 chủ đề đang làm việc tại thời gian và ngay sau khi một trong số họ được thực hiện mới có thể được bắt đầu.

Cảm ơn tất cả,

+0

Tại sao yêu cầu chỉ có 5 luồng hoạt động cùng một lúc? – Andrew

+0

Tôi muốn đặt cấu hình sau.Bây giờ tôi muốn gắn bó với 5. –

+0

Tại sao không để cho Fx quyết định có bao nhiêu chủ đề để sử dụng? Đó là mặc định với lớp ThreadPool, và nó làm một công việc tốt trong kinh nghiệm của tôi. –

Trả lời

4

Tôi bỏ phiếu cho task parallel library/Rx (bao gồm trong .NET 4.0, nhưng thể tải về 3.5):

 var options = new ParallelOptions(); 
     options.MaxDegreeOfParallelism = 5; 

     Parallel.ForEach(GetListOFiles(), options, (file) => 
     { 
      DoStuffWithFile(file); 
     }); 

Lưu ý rằng điều này sẽ sử dụng lên đến 5 chủ đề, nhưng tôi đã nhìn thấy nó sử dụng ít hơn.

2

Chia danh sách tệp của bạn thành 5 danh sách kích thước bằng nhau. Sau đó bắt đầu năm luồng và chuyển từng danh sách nhỏ hơn riêng lẻ qua ParameterizedThreadStart.

Tuy nhiên, vì công việc gần như hoàn toàn I/O bị ràng buộc, quá trình này không có khả năng hưởng lợi từ luồng.

+0

@Sam: Không chắc chắn về việc không có lợi ích từ IO đa luồng. Có dữ liệu tập tin được sao chép xung quanh trong bộ nhớ, hệ điều hành có kiến ​​thức tốt hơn về số lần đọc và có thể tối ưu hóa, đĩa có thể hỗ trợ IO song song (RAID?), V.v. Tất nhiên, người ta không thể nói cho đến khi chúng ta thực sự đo nó, là quá sớm để nói bất cứ điều gì về nó. –

4

Bạn nên có một cái nhìn tại

system.threading.threadpool.setmaxthreads

+1

Sử dụng setmaxthreads là không thực sự được đề nghị, trừ khi bạn thực sự biết những gì bạn đang làm. Bạn đang giới hạn luồng chia sẻ chung và các thư viện bạn sử dụng có thể sẽ bị ảnh hưởng bởi nó. –

+0

Tôi đã đưa ra điều này là -1, bởi vì thường là hành vi xấu để sử dụng điều này. –

1

Đừng xử lý của bạn thông qua ThreadPool, sau đó setMaxThreads

http://msdn.microsoft.com/en-us/library/system.threading.threadpool.setmaxthreads.aspx

+0

Sử dụng setmaxthreads là không thực sự được đề nghị, trừ khi bạn thực sự biết những gì bạn đang làm. Bạn đang giới hạn threadpool _shared_ và các thư viện bạn sử dụng có thể sẽ bị ảnh hưởng bởi nó. –

+0

Tôi đã đưa ra điều này là -1, bởi vì thực tế thường là không tốt để sử dụng điều này. –

2

Mặc dù điều này có thể không trả lời câu hỏi của bạn trực tiếp, nhưng có vẻ như a producer-consumer design sẽ phù hợp với nhu cầu của bạn. Ngoài ra, this có thể hữu ích.

2

Tôi thường thực hiện phương pháp này:

Khai báo biến số nguyên được chia sẻ để biểu thị số lượng chuỗi làm việc. Khi một công việc được gán cho một chủ đề (chỉ cần xếp hàng công việc vào ThreadPool), hãy tăng giá trị. Khi một chuỗi hoàn thành công việc, hãy giảm giá trị.

Đảm bảo giảm hoặc tăng giá trị nguyên như nguyên tử.

Trong bộ điều phối công việc, tìm nạp công việc và gán cho một chuỗi chỉ khi số chuỗi công việc nhỏ hơn giá trị lớn nhất. Nếu không, hãy đợi tín hiệu (sẽ được kích hoạt bởi một chuỗi hoạt động hoàn thành công việc). Nếu bạn muốn sự kiện đơn giản hơn, hãy để người điều phối chỉ cần làm vòng lặp trống để chờ.

Điểm tốt là giá trị tối đa có thể định cấu hình được và tận dụng lợi thế của ThreadPool tích hợp. Viết một mô hình người tiêu dùng/nhà sản xuất để giải quyết một vấn đề nhỏ như vậy là tốn kém.