reuse of threads (urgent)

K

Kovan Akrei

Hi,
I would like to know how to reuse an object of a thread (if it is possible)
in Csharp? I have the following program:

using System;
using System.Threading;
using System.Collections;

public class A
{
private Thread thread;
private static Queue q =new Queue();
public A()
{
thread = new Thread(new ThreadStart(this.Run));
}

private static void getThread(A a)
{
if (a.thread != null)
return;
else
if(q.count > 0)
// there are available threads
a.thread = (Thread) q.Dequeue();
// ** Here i have to tell a.thread to run a.Run method when
it starts **
// I do not know how to do that.
else
// make a new thread object
a.thread = new Thread(new ThreadStart(a.Run));
}

private void Run()
{
// do some work
thread.Sleep(1000);
//insert the thread objekt into a queue
q.Enqueue(thread);
thread = null;
}
} // A

This implementation does not work, because when a thread is assigned to a
new object of class A it has to know which method to execute. I know that I
could use a threadpool, but I do not want to because my program ( a
simulation) uses sometimes millions of threads. Threadpool allows only 25
threads by default. It is some how difficult to change this number in
Csharp.

Many thanks in advance :)

Regards from
Kovan
 
J

Jon Skeet [C# MVP]

Kovan Akrei said:
I would like to know how to reuse an object of a thread (if it is possible)
in Csharp?

Write a system where each thread knows about a list of work items, and
takes items off the list until the list is empty, then waits for the
list to have work items added to it. This is basically what the built-
in ThreadPool does anyway.

You should be aware that when you say you're going to use "millions of
threads" that's not actually going to happen - and even if it did,
performance would be excruciating.
 
N

Nicholas Paldino [.NET/C# MVP]

It should also be noted that the ThreadPool will allow you to create as
many ^requests^ as you wish. It just won't execute more than 25 threads
(this is the number currently assigned per processor, but is subject to
change).

So, in this situation, the ThreadPool will actually suit the original
poster's needs, as it will queue up all the work, and then execute when it
can. Like Jon said, there is no way you are going to get one million
threads to run at the same time. If anything, I bet the performance using
the thread pool would destroy the performance when creating one million
threads. I would think the context switches alone would kill you.

Hope this helps.
 
K

Kovan Akrei

Thanks for replying so fast :)

Jon Skeet said:
Write a system where each thread knows about a list of work items, and
takes items off the list until the list is empty, then waits for the
list to have work items added to it. This is basically what the built-
in ThreadPool does anyway.
The list you are talking about will get empty very fast in a simulation
program. Im trying to avoid creating new threads each time a new process
object in the simulation is about to be created. By doing so I'll avoid
allot of overhead. In my simulation program (discrete event simulation) I
get sometimes up to one hundred thousen threads running, but not all of them
are active at the same time. Some of them are in WaitSleep state, while
others are in running state (using cpu power). There are almost alyways more
than 25 threads in a running state. The problem with a thread pool is that
when a program has exhausted the pool other process which has to be executed
at once has to wait until there is a thread available in threadpool.
You should be aware that when you say you're going to use "millions of
threads" that's not actually going to happen - and even if it did,
performance would be excruciating.
I know. As I stated earlier. Not all of them are in a rrunning state, but
many of them are.

Kovan
 
K

Kovan Akrei

Read the poster i send to John :). The reply there is relevant to your
comments too .

Kovan

Nicholas Paldino said:
It should also be noted that the ThreadPool will allow you to create as
many ^requests^ as you wish. It just won't execute more than 25 threads
(this is the number currently assigned per processor, but is subject to
change).

So, in this situation, the ThreadPool will actually suit the original
poster's needs, as it will queue up all the work, and then execute when it
can. Like Jon said, there is no way you are going to get one million
threads to run at the same time. If anything, I bet the performance using
the thread pool would destroy the performance when creating one million
threads. I would think the context switches alone would kill you.

Hope this helps.
 
J

Jon Skeet [C# MVP]

The list you are talking about will get empty very fast in a simulation
program.

And that's fine.
Im trying to avoid creating new threads each time a new process
object in the simulation is about to be created.

And the above does exactly that - note that the thread waits until a
new work item has been added to the list, it doesn't just terminate
when the list is exhausted.
By doing so I'll avoid
allot of overhead. In my simulation program (discrete event simulation) I
get sometimes up to one hundred thousen threads running, but not all of them
are active at the same time.

I'd be surprised if you got to that many *real* threads. (See later.)
Some of them are in WaitSleep state, while
others are in running state (using cpu power). There are almost alyways more
than 25 threads in a running state.

Do you have 25 processors? If not, it's unlikely that it'll be working
very efficiently - the context switches will be hurting you.
The problem with a thread pool is that
when a program has exhausted the pool other process which has to be executed
at once has to wait until there is a thread available in threadpool.

Well, you could certainly write a threadpool which allowed items to be
added in "emergency" mode which made sure that if no threads were
available, a new one was created and added to the pool.

There are various reasons why the default threadpool implementation may
not suit you, but it's a good starting model. Consider how it works,
and what extra features you need - then write your own.
I know. As I stated earlier. Not all of them are in a rrunning state, but
many of them are.

Even so, just having a million threads *at all* is unlikely to get you
anywhere. You'll run out of handles long before that. Try the program
below:

using System;
using System.Threading;

class Test
{
static void Main()
{
for (int i=0; i < 1000000; i++)
{
if (i%100==0)
Console.WriteLine (i);
new Thread (new ThreadStart(Sleep)).Start();
}
}

static void Sleep()
{
Thread.Sleep (100000);
}
}

On my box, that terminates with an OutOfMemoryException somewhere
between 1800 and 1900 threads. What does it do on your box?
 
N

Nicholas Paldino [.NET/C# MVP]

Kovan,

I saw your reply to Jon's response, and I still think that you have too
many threads running at the same time. Have you actually tried the
ThreadPool to see what the difference in performance is? I still think that
the context switches on that many threads (as well as the resources required
to maintain that many threads, active or inactive, on the system).

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Kovan Akrei said:
Read the poster i send to John :). The reply there is relevant to your
comments too .

Kovan

message news:[email protected]...
It should also be noted that the ThreadPool will allow you to create as
many ^requests^ as you wish. It just won't execute more than 25 threads
(this is the number currently assigned per processor, but is subject to
change).

So, in this situation, the ThreadPool will actually suit the original
poster's needs, as it will queue up all the work, and then execute when it
can. Like Jon said, there is no way you are going to get one million
threads to run at the same time. If anything, I bet the performance using
the thread pool would destroy the performance when creating one million
threads. I would think the context switches alone would kill you.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Jon Skeet said:
I would like to know how to reuse an object of a thread (if it is possible)
in Csharp?

Write a system where each thread knows about a list of work items, and
takes items off the list until the list is empty, then waits for the
list to have work items added to it. This is basically what the built-
in ThreadPool does anyway.

You should be aware that when you say you're going to use "millions of
threads" that's not actually going to happen - and even if it did,
performance would be excruciating.
 
W

William Stacey

As Jon and others have said, you are counter productive with more then a few
threads in most cases. Threads can help you if they can actually do
different work while waiting for IO or if you need to give interactive feel
to a GUI or need to support state and interactivity for multiple clients at
once. Context switches are expensive and all threads will compete for the
execution path. Its like having 10 cooks in the kitchen, they all end up
running into each other and much less work is done then if one or two cooks
did things in an organized fashion. Lets take an example. Say you want to
send 100 different DNS queries and process the replies (assume one udp
request=one udp reply.) So you fire up 100 threads to send the requests
(lets look at just the request side for now.) So thread1 puts together a
packet and before it gets to send, thread2 gets the cpu and puts together a
packet, then thread3, etc. thread1 gets the cpu back and actually does udp
send, and thread2 does the same, at various times other threads wake up and
block waiting for the socket to free to post another send. This does not
help us with performance. We are switching away from thread1 before it can
finish just to start another request that may or may not get to post that
send and then switch back to post the first send. So I did not end up
posting either send in two context switches in that case (could be less,
could be *more.) That is like trying to paint two rooms at once - one
stroke on wall one, then run over to second room and do a stroke on that
wall and repeat. In the end, it would have been much faster to finish room1
and then move on to room2. So starting up 100 threads to send 100 requests
is not the answer, you up doing partial work on each for awhile and spending
a lot of time to context switches and waiting on IO (contension for the IP
stack.) The IP stack has a queue to, so you still end up in a hurry-up and
wait situation anyway at some point - many threads does not help here. A
better design would be to have one thread send requests (retreived from your
queue) asyncronously as fast as possible, one after the other in a tight
loop. The reply side has a similar story. There is no sense having 10
threads waiting for replies as each thread can only process so much work
before it gives up the cpu for another thread to process a section of code.
So your adding overhead without actually doing more work. So in your case,
your not trying to give an interactive "feel" to multiple clients (as in a
multi-threaded server service) your trying to go from point A to point B as
fast as possible (I assume from your text.) Two very good books on this
subject are:
- Win32 System Programming: A Windows(R) 2000 Application Developer's Guide
(2nd Edition)
- Multithreading Applications in Win32 : The Complete Guide to Threads
 
D

Dan

For anyone who is interested here is an interesting
article on building your own thread pool using the Win32
API. I have worked through the article and have tested
using the pool in "real" applications. It has worked great
for me.

http://www.devarticles.com/art/1/508
 
M

Mr.Tickle

Why build youre own when its already done in .net

You think you can do better? If you need more , just edit the .h file from
the default of 25 or add more CPUs :D
 
J

Jon Skeet [C# MVP]

Mr.Tickle said:
Why build youre own when its already done in .net

Because there are various problems with the existing threadpool:

o No control over when threads are created
o No control over how many threads are created
o No control over when/if threads are terminated
o Thread pool is shared between all applications (I think - not
absolutely sure on this one)
o Thread pool is also used by other classes in the .NET framework
which can cause problems

It's fine for many things, but not ideal for everyone.
 
K

Kovan Akrei

Hi folks,
Thank you all for your contribution. In this email I'll try to explain why I
need to develop a simple threadpool manager (regardles of OS) of my own and
not use the built in ThreadPool class.
I'm a master degree student who is trying to write a discrete event
simulation package in C#. In this process I have to develop a coroutine
package (as stated in the programing language Simula) using .Net threads. I
have done this job and I'm trying now to optimize the package.

For those of you who are not familier with coroutines:
Coroutines are a light version threads introduced by Simula in the 60. They
are light threads in the sence that they work in quasi parallell. Many
coroutine can run at the same time, but ONLY ONE coroutine will be executing
at a time regardless of the number of CPUs.
Unlike threads, coroutines are able to pass the control explicitly to each
other. For example a coroutine A is able to pass the controll explicitly to
another coroutine B by the means of resume(B) or call(B) methods (Simula
keywords). Sence you cant do this with threads, we have to controll threads
some how and make sure that thread A passes the control to thread B and only
B. To do so , we have to syncronise threads by means of lock, notify and
wait statements (keep track of their execution state) and by doing so you
cant use threadpool sence you do not have any control of the threads running
in a threadpool.

Making and administrating threads requires allot of overhead which slows
down my package. Now I'm trying some how to economize the thread usage by
reusing threads that already has been made available by means of keyword
new.

I was thinking that when a thread is made it executes a certain coroutine
and remains executing the same coroutine until the coroutine is finished.
After that the thread inserts itself into a list of free threads. Next time
a coroutine objekt wants to be executed it uses a thread from among the
free/available threads on the list. If there were no free threads then it
should make a new thread. This way I'll keep the number of threads made to
the minimum reducing the memory usage and improve performance.

Many regards
Kovan
 
D

Dave

Because there are various problems with the existing threadpool:

o No control over when threads are created
o No control over how many threads are created
o No control over when/if threads are terminated
o Thread pool is shared between all applications (I think - not
absolutely sure on this one)
FYI: each Win32 process (application) that hosts the CLR is completely
separate so each would get its own thread pool. The thread pool is shared
amongst all the separate appdomains within a single win32 process.
o Thread pool is also used by other classes in the .NET framework
which can cause problems

Other potential issues:
* A single thread pool
* All threads run at the same priority.
* Cannot reserve a block of threadpool threads for specific purposes (e.g.
out of band data that must be serviced ASAP)
* Custom security settings

It's fine for many things, but not ideal for everyone.
Agreed. It's fine for lots of general purpose uses.
 
J

Jon Skeet [C# MVP]

FYI: each Win32 process (application) that hosts the CLR is completely
separate so each would get its own thread pool. The thread pool is shared
amongst all the separate appdomains within a single win32 process.

Sorry, yes - that's what I meant. There could be multiple applications
(such as webapps) running within the same CLR. Sorry not to be clearer
- applications wasn't a good word to use.
Other potential issues:
* A single thread pool
* All threads run at the same priority.
* Cannot reserve a block of threadpool threads for specific purposes (e.g.
out of band data that must be serviced ASAP)
* Custom security settings

Yup.
 
D

Dave

Sorry, yes - that's what I meant. There could be multiple applications
(such as webapps) running within the same CLR. Sorry not to be clearer
- applications wasn't a good word to use.
Yup. And congrats on the MVP status.
 
K

Kovan Akrei

Why build youre own when its already done in .net, well the built in does not fit my needs.
You think you can do better? If you need more , just edit the .h file from
the default of 25 or add more CPUs :D
That is not the issue. What I need is have to work with my implementation.
If you read my extra notes to my original post you might get a better view
of what I'm looking for.

Kovan
 
K

Kovan Akrei

Hi,
I have posted a reply to my original post where I explain my problemes a
little more in depth. I would appreciate if you (and everybody else) could
read that and write som comments.

Kovan

Nicholas Paldino said:
Kovan,

I saw your reply to Jon's response, and I still think that you have too
many threads running at the same time. Have you actually tried the
ThreadPool to see what the difference in performance is? I still think that
the context switches on that many threads (as well as the resources required
to maintain that many threads, active or inactive, on the system).

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Kovan Akrei said:
Read the poster i send to John :). The reply there is relevant to your
comments too .

Kovan

message news:[email protected]... create
as
when
it
can. Like Jon said, there is no way you are going to get one million
threads to run at the same time. If anything, I bet the performance using
the thread pool would destroy the performance when creating one million
threads. I would think the context switches alone would kill you.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

I would like to know how to reuse an object of a thread (if it is
possible)
in Csharp?

Write a system where each thread knows about a list of work items, and
takes items off the list until the list is empty, then waits for the
list to have work items added to it. This is basically what the built-
in ThreadPool does anyway.

You should be aware that when you say you're going to use "millions of
threads" that's not actually going to happen - and even if it did,
performance would be excruciating.
 
D

Dave

On my box, that terminates with an OutOfMemoryException somewhere
between 1800 and 1900 threads. What does it do on your box?

re: millions of threads....that's simply not possible on the standard
windows OS. Each thread is given a default stack size of 1Mbyte, and the max
amount of virtual address space per win32 process is 2Gbyte, hence the upper
limit of about 2000 threads. Thus the out of memory exception you see at
that number of threads. The original creator of this thread was simply
mistaken about his creating hundreds of thousands of threads. He may have
that many work items but not threads.
 
B

bwahahahaha

you normally get about 800 to 900 per 1gb machine.


Thats the experience I had, so if you get millions, how much ram do you
have??? the mind boggles.
 
K

Kovan Akrei

re: millions of threads....that's simply not possible on the standard
I ment in theory.
windows OS. Each thread is given a default stack size of 1Mbyte, and the max
amount of virtual address space per win32 process is 2Gbyte, hence the upper
limit of about 2000 threads. Thus the out of memory exception you see at
that number of threads. The original creator of this thread was simply
mistaken about his creating hundreds of thousands of threads. He may have
that many work items but not threads.
Not all of them are active at the same time. May be I was not that clear in
my original posting. I didn't mean that you should run millions of threads.
I ment that the system (my system) could generate millions of threads where
many (thousends??) of them could be active at the same time (read my extra
notes to my original post).

Kovan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top