25

If my understanding of the way the ThreadPool works is correct, one of its purposes is to limit the number of worker threads within a process that can be created at a given time. For example, if you set MaxThreads to 5 and then call QueueUserWorkItem 30 times, 30 requests will be made to the ThreadPool, but only 5 of those requests will be serviced by a new thread, while the other 25 requests will be added to the queue and serviced one at time as previous requests complete and existing threads becomes available.

In the code below, however, the call to Thread.Sleep(-1) guarantees that the DoSomething() method will never return, meaning that the current thread will never become available to subsequent requests.

But my understanding of the way a ThreadPool works cannot be correct, because if it were correct the code below would print only the numbers 0-4, rather than 0-29.

Can someone please explain how the ThreadPool works and why the below code isn't doing what I thought it should be doing?

    static void DoSomething(object n)
    {
        Console.WriteLine(n);
        Thread.Sleep(-1);
    }

    static void Main(string[] args)
    {
        ThreadPool.SetMaxThreads(5, 5);
        for (int x = 0; x < 30; x++)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomething), x);
        }
        Console.Read();
    }
John Smith
  • 4,416
  • 7
  • 41
  • 56

4 Answers4

19

ThreadPool.SetMaxThreads(5, 5)

means the number of active thread is 5 (if you have more than 5 cpu core), does not mean that the ThreadPool can only create 5 threads. The ThreadPool maximum number of threads = CPU Core * 250.

After Thread.Sleep, the thread is inactive, so it will not affect the execution of other threads.

Butzke
  • 561
  • 1
  • 14
  • 30
shalongbus
  • 226
  • 2
  • 3
  • that helps. If I replace Sleep() with an infinite loop, there is a different behavior. still not what I expected, but different... – John Smith Jan 25 '13 at 21:28
  • is this formula for maximum number of threads i.e MaxThreads=(CPU*250) is defined somewhere in thread or ThreadPool class ? – SHEKHAR SHETE Feb 23 '16 at 09:59
4

But my understanding of the way a ThreadPool works cannot be correct, because if it were correct the code below would print only the numbers 0-4, rather than 0-29.

Yes your assumption is very much correct.

Since u have queued 30 jobs in a ThreadPool and the Jobs will sleep for InfiniteTime, they will never finish, the ThreadPool class will wait for a certain interval to create new thread, but will not exceed the max number of threads.

NOTE

Console.Read() is keeping your Background thread alive.

Articles

From MSDN

Many applications create threads that spend a great deal of time in the sleeping state, waiting for an event to occur. Other threads might enter a sleeping state only to be awakened periodically to poll for a change or update status information. Thread pooling enables you to use threads more efficiently by providing your application with a pool of worker threads that are managed by the system. One thread monitors the status of several wait operations queued to the thread pool. When a wait operation completes, a worker thread from the thread pool executes the corresponding callback function.


When all thread pool threads have been assigned to tasks, the thread pool does not immediately begin creating new idle threads. To avoid unnecessarily allocating stack space for threads, it creates new idle threads at intervals. The interval is currently half a second, although it could change in future versions of the .NET Framework.


The threads in the managed thread pool are background threads. That is, their IsBackground properties are true. This means that a ThreadPool thread will not keep an application running after all foreground threads have exited.

Community
  • 1
  • 1
Parimal Raj
  • 20,189
  • 9
  • 73
  • 110
2

It may be that the Thread.Sleep(-1) is not doing what you expect.

Parameter Int32: The number of milliseconds for which the thread is blocked. Specify zero (0) to indicate that this thread should be suspended to allow other waiting threads to execute. Specify Infinite to block the thread indefinitely.

http://msdn.microsoft.com/en-us/library/d00bd51t.aspx

You should look into Tasks, http://msdn.microsoft.com/en-us/library/dd235608.aspx Think of it as Threadpool 2.0

Austin Harris
  • 1,676
  • 1
  • 17
  • 22
0

Usually, ThreadPool creates a number of threads equal to number of CPU cores. There are no necessity in creating more threads as only one thread could be handled by core in a time. But, when task queued to a ThreadPool takes more than 0.5s to execute, the ThreadPool creates an additional thread to handle remaining tasks in a queue. So, if you queue a lot of heavy tasks to a ThreadPool, it will create a lot of additional threads to emulate multitasking and execute all tasks in "parallel". But total execution time would be the same as without additional threads, moreover, it would be even less because creation the thread is quite heavy operation. That's why ThreadPool is recommended for small tasks, to avoid creation additional threads which actually do not bring any advantage.

You can read more about ThreadPool in Albahari's article. Actually, he has a good set of articles there about threading.

  • i am confused between these two sentences: 'ThreadPool creates a number of threads equal to number of CPU cores' and 'ThreadPool maximum number of threads = CPU Core * 250.'(as wrote in accepted answer above) which one is right ? – SHEKHAR SHETE Feb 23 '16 at 10:17
  • Both. The number of threads is equal to the number of CPU cores and usually it is enough if you follow guidelines, i.e. use ThreadPool for quick computational operations. But, if you manage to load all its threads and then queue another task, it will wait for about 0.5 seconds for any existing threads to be released and if none of them is released it will create an extra thread to process your task. Then, when all tasks are completed and threads are released, it will kill redundant threads. – Sergii Vashchyshchuk Feb 27 '16 at 10:47