简体   繁体   中英

Is Thread managed by the thread pool?

I know that the CLR gives each AppDomain ThreadPool time slice to work , yet i wanted to know if by creating a new thread like so Thread t = new Thread(...);

Is it managed by the CLR or by the AppDomin ThreadPool ?

Thread t = new Thread(); will not be managed by the ThreadPool . But it is an abstraction provided by the CLR on the Operating System threads. ThreadPool is an addtional abstraction which facilitates reusing threads and sharing thread resources.

Here is an excellent resource on threads in .NET: http://www.albahari.com/threading/

If you're using .NET 4.0 consider using TPL.

When you create threads with the Thread class, you are in control. You create them as you need them, and you define whether they are background or foreground (keeps the calling process alive), you set their Priority , you start and stop them.

With ThreadPool or Task (which use the ThreadPool behind the scenes) you let the ThreadPool class manage the creation of threads, and maximizes reusability of threads, which saves you the time needed to create a new thread. One thing to notice is that unlike the Thread default, threads created by the ThreadPool don't keep the calling process alive.

A huge advantage of using the ThreadPool is that you can have a small number of threads handle lots of tasks. Conversely, given that the pool doesn't kill threads (because it's designed for reusability), if you had a bunch of threads created by the ThreadPool , but later the number of items shrinks, the ThreadPool idles a lot, wasting resources.

创建新线程时,它们不受线程池管理。

如果手动创建线程然后控制其生命周期,则它独立于线程池。

The following example shows how to use a thread pool. It first creates a ManualResetEvent object, which enables the program to know when the thread pool has finished running all of the work items. Next, it attempts to add one thread to the thread pool. If this succeeds, it adds the rest (four in this example). The thread pool will then put work items into available threads. The WaitOne method on eventX is called, which causes the rest of the program to wait until the event is triggered (with the eventX.Set method). Finally, the program prints out the load (the thread that actually executes a particular work item) on the threads.

    // 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM