From: Tony Johansson on
Hi!

At the end is text from the e-learning. I just made a check I started 100
threads from the Threadpool and used a very long sleep for each one and it
worked to create at least 100 threads. So what the text say about 25 is that
wrong perhaps ?

There is a limit of 25 threads in a thread pool; therefore, even if you
start 50 threads, only 25 threads will be executed at a given time. As soon
as a thread finishes, another thread that was waiting for an idle thread in
the pool can start.

//Tony


From: Arne Vajhøj on
On 14-05-2010 20:15, Tony Johansson wrote:
> At the end is text from the e-learning. I just made a check I started 100
> threads from the Threadpool and used a very long sleep for each one and it
> worked to create at least 100 threads. So what the text say about 25 is that
> wrong perhaps ?
>
> There is a limit of 25 threads in a thread pool; therefore, even if you
> start 50 threads, only 25 threads will be executed at a given time. As soon
> as a thread finishes, another thread that was waiting for an idle thread in
> the pool can start.

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

says:

<quote>
There is one thread pool per process. The thread pool has a default size
of 250 worker threads per available processor, and 1000 I/O completion
threads. The number of threads in the thread pool can be changed by
using the SetMaxThreads method. Each thread uses the default stack size
and runs at the default priority.
</quote>

Try creating 300 work items. Or call SetMaxThreads with 25.

Arne


From: Patrice on
Hello,

> At the end is text from the e-learning. I just made a check I started 100
> threads from the Threadpool and used a very long sleep for each one and it
> worked to create at least 100 threads. So what the text say about 25 is
> that wrong perhaps ?

In addition to Arne and as a side note, I would recommend to avoid using
Sleep when writing threading test code. This is because Sleep doesn't
simulate a working thread but *suspend* the thread... So when used with a
backgroundworker for example it will give some time to the UI thread (when a
truly working thread would not) and for the threadpool it won't count as an
active thread.

Also knowing what you expect when you create "too much" threads could help.

Try :
http://msdn.microsoft.com/en-us/library/0ka9477y(v=VS.80).aspx

IMO it's always best to check first what tells the exam book agains the
documentation. For now I see :

"The number of operations that can be queued to the thread pool is limited
only by available memory; however, the thread pool limits the number of
threads that can be *active* in the process simultaneously. By default, the
limit is 25 worker threads per CPU and 1,000 I/O completion threads."

-
Patrice

From: Peter Duniho on
Patrice wrote:
> Hello,
>
>> At the end is text from the e-learning. I just made a check I started
>> 100 threads from the Threadpool and used a very long sleep for each
>> one and it worked to create at least 100 threads. So what the text say
>> about 25 is that wrong perhaps ?
>
> In addition to Arne and as a side note, I would recommend to avoid using
> Sleep when writing threading test code. This is because Sleep doesn't
> simulate a working thread but *suspend* the thread... So when used with
> a backgroundworker for example it will give some time to the UI thread
> (when a truly working thread would not) and for the threadpool it won't
> count as an active thread. [...]

That's not really true. First, the UI thread will get CPU time whether
or not another thread is using Sleep(). It is true that less CPU time
is available if the test threads are not using Sleep(), but the UI
thread doesn't normally need a _lot_ of CPU time.

Second, the ThreadPool class has no idea whether its worker threads are
stuck waiting on a call to Sleep() or actually doing work. As far as
the ThreadPool class is concerned a thread that's called Sleep() and is
waiting to be woken up is just as "active" as any other thread pool
thread that's doing real work.

Pete
From: Peter Duniho on
Peter Duniho wrote:
> Patrice wrote:
>> Hello,
>>
>>> At the end is text from the e-learning. I just made a check I started
>>> 100 threads from the Threadpool and used a very long sleep for each
>>> one and it worked to create at least 100 threads. So what the text
>>> say about 25 is that wrong perhaps ?
>>
>> In addition to Arne and as a side note, I would recommend to avoid
>> using Sleep when writing threading test code. This is because Sleep
>> doesn't simulate a working thread but *suspend* the thread... So when
>> used with a backgroundworker for example it will give some time to the
>> UI thread (when a truly working thread would not) and for the
>> threadpool it won't count as an active thread. [...]
>
> That's not really true. First, the UI thread will get CPU time whether
> or not another thread is using Sleep(). It is true that less CPU time
> is available if the test threads are not using Sleep(), but the UI
> thread doesn't normally need a _lot_ of CPU time. [...]

To clarify the above in a more specific way:

Thread quantum is something like 50ms (I think maybe more than 55ms, but
it's been a long time since I needed to know specifically and I'm not
going to try to look it up now :) ).

If you've got 1000 active threads, plus the GUI thread, all running at
the same priority, then the GUI thread is only going to get access to
the CPU every 50,000 ms, or about once a minute (every 50 seconds).

Obviously, that's not very good and it's true that if those 1000
"active" threads are actually sitting at a call to Sleep(), they won't
interfere with the GUI thread in the same way.

But with only 100 threads (as Tony suggests), the GUI thread will get to
run every 5 seconds even with active threads, and that assumes the
threads are really 100% CPU-bound, which is rarely the case (often
threads can do only so much work before they need input from somewhere
else, either another thread or some i/o, that sort of thing). With
threads that aren't using their entire quantum, the delay for the GUI
thread is even lower.

And of course, all this assumes just one CPU core, which is getting to
be pretty unusual. With more cores, the threads get through their
round-robin sequence faster, in proportion to the number of cores.

Anyway, my point is that the statement "it will give some time to the UI
thread (when a truly working thread would not)" implies that if the
thread is 100% CPU bound, the UI thread won't get any CPU time at all.
It's that implication that I was commenting on.

Finally (not a response to Patrice's comments per se, but just something
related to the overall question) note that for truly CPU-bound tasks,
especially those that are expected to take some significant time, it is
better for the thread to lower its priority, specifically so that
threads like the GUI thread (which almost never will use up a
significant portion of its quantum, never mind all of it) can still
provide responsive behavior to the user, without any appreciable
reduction in throughput on the threads that are really doing work.

Pete