13

Có đọc Parallel.ForEach keeps spawning new threads Tôi vẫn còn nghi ngờ cho dù đó là một phương pháp chính xác để đếm số lượng đồng thời có chủ đề?Làm thế nào để đếm số lượng các chủ đề đồng thời trong ứng dụng .NET?

Điều tôi thấy là phương pháp tính số lần lặp lại đồng thời nhưng không hoàn thành (vòng lặp) trong Parallel.ForEach.
Có phải từ đồng nghĩa của số lượng các chuỗi đồng thời truyền đạt đúng số lượng các chuỗi chạy đồng thời không?
Tôi không phải là chuyên gia nhưng tôi có thể tưởng tượng rằng:

  • các chủ đề có thể được tái sử dụng trong khi hoạt động của nó hoán đổi đâu đó để tiếp tục sau đó.
  • lý thuyết thread tham gia vào một hoạt động vòng lặp được lưu giữ trong hồ bơi thread sau một kết thúc vòng lặp nhưng không tái sử dụng cho một
  • Hoặc các khả năng xuyên tạc sự tinh khiết của thí nghiệm (của đề đếm) là gì?

Dù sao, làm cách nào để trực tiếp đếm số lượng các luồng đang chạy của tiến trình .NET, tốt nhất là trong mã (C#)?

Cập nhật:

Vì vậy, nếu đi theo Jeppe Stig Nielsen's answer và sử dụng cho đếm

directThreadsCount = Process.GetCurrentProcess().Threads.Count; 

sau đó đầu ra là, cả hai trong phiên bản lần (threadsCount == 7) và Debug (threadsCount == 15) chế độ rất giống:

[Job 0 complete. 2 threads remaining but directThreadsCount == 7 
[Job 1 complete. 1 threads remaining but directThreadsCount == 7 
[Job 2 complete. 2 threads remaining but directThreadsCount == 7 
[Job 4 complete. 2 threads remaining but directThreadsCount == 7 
[Job 5 complete. 2 threads remaining but directThreadsCount == 7 
[Job 3 complete. 2 threads remaining but directThreadsCount == 7 
[Job 6 complete. 2 threads remaining but directThreadsCount == 7 
[Job 9 complete. 2 threads remaining but directThreadsCount == 7 
[Job 7 complete. 1 threads remaining but directThreadsCount == 7 
[Job 8 complete. 0 threads remaining but directThreadsCount == 7 
FINISHED 

Tức là, số lượng chủ đề không bao giờ giảm nói rằng the cited above method là không chính xác khi System.Diagnostics.ProcessThread cho "Class name is not valid at this point"

Are kết luận của tôi đúng và tại sao không thể được sử dụng ProcessThread?

Các sử dụng mã của C# console ứng dụng:

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Linq; 
using System.Threading; 
using System.Threading.Tasks; 

namespace Edit4Posting 
{ 
public class Node 
{ 

    public Node Previous { get; private set; } 
    public Node(Node previous) 
    { 
    Previous = previous; 
    } 
    } 
    public class Edit4Posting 
    { 

    public static void Main(string[] args) 
    { 
     int concurrentThreads = 0; 
     int directThreadsCount = 0; 
     int diagThreadCount = 0; 

     var jobs = Enumerable.Range(0, 10); 
     Parallel.ForEach(jobs, delegate(int jobNr) 
     { 
     int threadsRemaining = Interlocked.Increment(ref concurrentThreads); 

     int heavyness = jobNr % 9; 

     //Give the processor and the garbage collector something to do... 
     List<Node> nodes = new List<Node>(); 
     Node current = null; 
     //for (int y = 0; y < 1024 * 1024 * heavyness; y++) 
     for (int y = 0; y < 1024 * 24 * heavyness; y++) 
     { 
      current = new Node(current); 
      nodes.Add(current); 
     } 
     //******************************* 
     //uncommenting next line gives: "Class name is not valid at this point" 
     //diagThreadCount=System.Diagnostics.ProcessThread 
     directThreadsCount = Process.GetCurrentProcess().Threads.Count; 
     //******************************* 
     threadsRemaining = Interlocked.Decrement(ref concurrentThreads); 
     Console.WriteLine(
      "[Job {0} complete. {1} threads remaining but directThreadsCount == {2}", 
      jobNr, threadsRemaining, directThreadsCount); 
     }); 
     Console.WriteLine("FINISHED"); 
     Console.ReadLine(); 
    } 
    } 
} 

Trả lời

34

Có nhiều loại chủ đề khác nhau, tôi nghĩ vậy. Chủ đề của hệ điều hành cho ứng dụng bạn đang chạy, có thể được tính với:

int number = Process.GetCurrentProcess().Threads.Count; 

Có vẻ như đếm được System.Diagnostics.ProcessThread trường hợp. Có lẽ bạn cần phải đếm một loại sợi khác, như "chuỗi được quản lý", vì vậy tôi không chắc chắn câu trả lời của tôi là những gì bạn tìm kiếm.

+0

Về lý thuyết,' Thread's và 'ProcessThread' có thể khác nhau. Trong thực tế, chúng hầu như luôn giống nhau. – svick

+0

@svick Một ứng dụng giao diện điều khiển rất đơn giản viết ra thuộc tính trên, cho '4', đôi khi' 3'. Tôi nghĩ đó là một ứng dụng một luồng. Khi cùng một ứng dụng được gỡ rối (trình gỡ lỗi đính kèm), số này cao hơn nhiều, như '12' hoặc' 13'.Trong một ứng dụng khác, nếu tôi bắt đầu rất nhiều luồng mới với lớp 'System.Threading.Thread', số đếm' System.Diagnostics.ProcessThread' tăng lên xấp xỉ bằng số chính xác. (Đã thử trên Windows 7 64 bit.) –

11

Tôi không phải là chuyên gia nhưng tôi có thể tưởng tượng rằng các chủ đề có thể được tái sử dụng trong khi hoạt động của nó hoán đổi đâu đó.

Không - ngoài một số trường hợp cụ thể (mà bạn gần như chắc chắn không cần phải lo lắng) không sử dụng reentrantly. Chủ đề sẽ được sử dụng lại để chạy lặp lại khác (hoặc một số tác vụ khác) sau khi lặp lại hiện tại đã hoàn tất, nhưng sẽ không yêu cầu làm điều gì khác trong khi mã của bạn đang chạy.

Vì vậy, về cơ bản, phương pháp tiếp cận của bạn là hợp lý.

Dù sao, làm cách nào để trực tiếp đếm số lượng chuỗi đang chạy trong .NET?

Bạn có thể tìm trong perfmon, biểu đồ sẽ hiển thị cho bạn. (Nếu quá trình này nằm dưới sự kiểm soát của bạn, đơn giản nhất là bắt đầu quá trình nhưng làm cho nó chờ đầu vào, sau đó mở ra perfmon, thêm bộ đếm từ tùy chọn "Process", chọn "Count Count" làm bộ đếm để thêm và hạn chế . nó đến quá trình bạn đang quan tâm từ menu thả xuống Nhấn OK, và sau đó làm cho quá trình của bạn bắt đầu làm việc)

EDIT:. để trả lời các cập nhật:

đó là, số lượng đề là không bao giờ giảm nói rằng phương pháp được trích dẫn ở trên không chính xác

Không, tất cả đều hiển thị là số lượng chuỗi hoạt động ely chạy mã của bạn giảm, nhưng các chủ đề được giữ xung quanh. Đó là hoàn toàn tự nhiên cho một hồ bơi thread.

tại sao không thể sử dụng ProcessThread?

Bạn chỉ đơn giản sử dụng nó một cách không thích hợp. Jeppe nói rằng hệ thống được đếm các trường hợp ProcessThread trong khi mã của bạn cố gắng gán một lớp học để một biến:

diagThreadCount=System.Diagnostics.ProcessThread 

Đó là mã đơn giản không hợp lệ. Thông báo lỗi cho thấy trình biên dịch nhận ra đó là tên của một loại, nhưng bạn không thể chỉ gán một tên kiểu cho một biến.

+0

Jon, Bạn có thể xem câu hỏi được cập nhật của tôi không? – Fulproof

+0

@Fulproof: Xong. Xem chỉnh sửa của tôi. –

+0

'diagThreadCount = System.Diagnostics.ProcessThread' không phải là mã hoàn chỉnh, tôi không thể hoàn thành nó vì Intellisense và trình biên dịch đưa ra một lỗi và từ chối sử dụng' ProcessThread' – Fulproof

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