Управляется ли поток пулом потоков? - PullRequest
4 голосов
/ 29 сентября 2011

Я знаю, что CLR дает каждый AppDomain ThreadPool интервал времени для работы, но я хотел знать, создавая новый поток, как это Thread t = new Thread(...);

Управляется ли он CLR или AppDomin ThreadPool?

Ответы [ 5 ]

6 голосов
/ 29 сентября 2011

Thread t = new Thread(); не будет управляться ThreadPool. Но это абстракция, предоставляемая CLR в потоках операционной системы. ThreadPool - это дополнительная абстракция, которая облегчает повторное использование потоков и совместное использование ресурсов потоков.

Вот отличный ресурс по потокам в .NET: http://www.albahari.com/threading/

Если вы используете .NET 4.0, рассмотрите возможность использования TPL.

3 голосов
/ 30 сентября 2011

Когда вы создаете темы с классом Thread, вы контролируете. Вы создаете их так, как вам нужно, и определяете, являются ли они фоном или передним планом (поддерживает процесс вызова), вы устанавливаете их Priority, запускаете и останавливаете их.

С ThreadPool или Task (которые используют ThreadPool за кадром) вы позволяете классу ThreadPool управлять созданием потоков и максимизирует возможность повторного использования потоков, что экономит ваше время, необходимое для создания новой темы. Следует отметить, что в отличие от Thread по умолчанию потоки, созданные ThreadPool, не поддерживают вызывающий процесс живым.

Огромным преимуществом использования ThreadPool является то, что вы можете иметь небольшое количество потоков, обрабатывающих множество задач. И наоборот, учитывая, что пул не уничтожает потоки (потому что он предназначен для многократного использования), если у вас есть набор потоков, созданный ThreadPool, но позже количество элементов уменьшается, ThreadPool много простаивает, тратя впустую ресурсы.

1 голос
/ 29 сентября 2011

Если вы создаете поток вручную, тогда вы контролируете его время жизни, это не зависит от пула потоков.

1 голос
/ 29 сентября 2011

При создании новых потоков они не управляются пулом потоков.

0 голосов
/ 18 июля 2012

В следующем примере показано, как использовать пул потоков. Сначала он создает объект ManualResetEvent, который позволяет программе узнать, когда пул потоков завершил выполнение всех рабочих элементов. Затем он пытается добавить один поток в пул потоков. Если это удается, он добавляет остальные (четыре в этом примере). Затем пул потоков помещает рабочие элементы в доступные потоки. Вызывается метод WaitOne для eventX, который заставляет остальную часть программы ждать, пока событие не будет запущено (с помощью метода eventX.Set). Наконец, программа распечатывает нагрузку (поток, который фактически выполняет определенный рабочий элемент) в потоках.

    // SimplePool.cs
// Simple thread pool example
using System;
using System.Collections;
using System.Threading;

// Useful way to store info that can be passed as a state on a work item
public class SomeState
{
   public int Cookie;
   public SomeState(int iCookie)
   {
      Cookie = iCookie;
   }
}

public class Alpha
{
   public Hashtable HashCount;
   public ManualResetEvent eventX;
   public static int iCount = 0;
   public static int iMaxCount = 0;
   public Alpha(int MaxCount) 
   {
      HashCount = new Hashtable(MaxCount);
      iMaxCount = MaxCount;
   }

   // Beta is the method that will be called when the work item is
   // serviced on the thread pool.
   // That means this method will be called when the thread pool has
   // an available thread for the work item.
   public void Beta(Object state)
   {
      // Write out the hashcode and cookie for the current thread
      Console.WriteLine(" {0} {1} :", Thread.CurrentThread.GetHashCode(),
         ((SomeState)state).Cookie);
      // The lock keyword allows thread-safe modification
      // of variables accessible across multiple threads.
      Console.WriteLine(
         "HashCount.Count=={0}, Thread.CurrentThread.GetHashCode()=={1}",
         HashCount.Count, 
         Thread.CurrentThread.GetHashCode());
      lock (HashCount) 
      {
         if (!HashCount.ContainsKey(Thread.CurrentThread.GetHashCode()))
            HashCount.Add (Thread.CurrentThread.GetHashCode(), 0);
         HashCount[Thread.CurrentThread.GetHashCode()] = 
            ((int)HashCount[Thread.CurrentThread.GetHashCode()])+1;
      }

      // Do some busy work.
      // Note: Depending on the speed of your machine, if you 
      // increase this number, the dispersement of the thread
      // loads should be wider.
      int iX  = 2000;
      Thread.Sleep(iX);
      // The Interlocked.Increment method allows thread-safe modification
      // of variables accessible across multiple threads.
      Interlocked.Increment(ref iCount);
      if (iCount == iMaxCount)
      {
         Console.WriteLine();
         Console.WriteLine("Setting eventX ");
         eventX.Set();
      }
   }
}

public class SimplePool
{
   public static int Main(string[] args)
   {
      Console.WriteLine("Thread Pool Sample:");
      bool W2K = false;
      int MaxCount = 10;  // Allow a total of 10 threads in the pool
      // Mark the event as unsignaled.
      ManualResetEvent eventX = new ManualResetEvent(false);
      Console.WriteLine("Queuing {0} items to Thread Pool", MaxCount);
      Alpha oAlpha = new Alpha(MaxCount);  // Create the work items.
      // Make sure the work items have a reference to the signaling event.
      oAlpha.eventX = eventX;
      Console.WriteLine("Queue to Thread Pool 0");
      try
      {
         // Queue the work items, which has the added effect of checking
         // which OS is running.
         ThreadPool.QueueUserWorkItem(new WaitCallback(oAlpha.Beta),
            new SomeState(0));
         W2K = true;
      }
      catch (NotSupportedException)
      {
         Console.WriteLine("These API's may fail when called on a non-Windows 2000 system.");
         W2K = false;
      }
      if (W2K)  // If running on an OS which supports the ThreadPool methods.
      {
         for (int iItem=1;iItem < MaxCount;iItem++)
         {
            // Queue the work items:
            Console.WriteLine("Queue to Thread Pool {0}", iItem);
            ThreadPool.QueueUserWorkItem(new WaitCallback(oAlpha.Beta),new SomeState(iItem));
         }
         Console.WriteLine("Waiting for Thread Pool to drain");
         // The call to exventX.WaitOne sets the event to wait until
         // eventX.Set() occurs.
         // (See oAlpha.Beta).
         // Wait until event is fired, meaning eventX.Set() was called:
         eventX.WaitOne(Timeout.Infinite,true);
         // The WaitOne won't return until the event has been signaled.
         Console.WriteLine("Thread Pool has been drained (Event fired)");
         Console.WriteLine();
         Console.WriteLine("Load across threads");
         foreach(object o in oAlpha.HashCount.Keys)
            Console.WriteLine("{0} {1}", o, oAlpha.HashCount[o]);
      }
      return 0;
   }
}

Out put

Thread Pool Sample:
Queuing 10 items to Thread Pool
Queue to Thread Pool 0
Queue to Thread Pool 1
...
...
Queue to Thread Pool 9
Waiting for Thread Pool to drain
 98 0 :
HashCount.Count==0, Thread.CurrentThread.GetHashCode()==98
 100 1 :
HashCount.Count==1, Thread.CurrentThread.GetHashCode()==100
 98 2 :
...
...
Setting eventX
Thread Pool has been drained (Event fired)

Load across threads
101 2
100 3
98 4
102 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...