473,466 Members | 1,326 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Am I using ThreadPool the right way?

Hello everybody,

I'm programming a TCP server.
During the stress tests I noticed that maybe my socket-receiving thread
became deaf after an hour of heavy stress.
I think that the reason could be this: The processing of the received
messages. Something goes wrong in this processing and the code gets stuck
here. As the processing is within the receiving "while" loop, the loop gets
also stuck, so that we will never reach again the Socket.Receive invoke;
thereafter we are deaf.

Besides I disliked the idea of processing the message within the receiving
loop. Somehow I understand that receving should be more "disconnected" from
the rest of the code.

So I thought of a different thread, asynchronously processing the received
message.
And, as after heavy stress this thread could get stuck as I said, I thought
of using the ThreadPool (even though one processing-thread gets stuck, the
following messages will be processed anyway, because ThreadPool will give us
a new thread to do this).

So, code would be something like this:
------------------------
int nRes = 0;
Byte[] buffer = new Byte[MAX_RECV_SIZE];
try
{
nRes = m_pSocket.Receive(buffer, MAX_RECV_SIZE, SocketFlags.None);
}
catch ...
....
string msg = Encoding.ASCII.GetString(buffer, 0, nRes);
sLog = String.Format("[pbx] CTIServer {0} < recv: '{1}'",
getPbxStringId(), msg);
m_maq.log.logNormal(3, sLog);
try
{
ThreadPool.QueueUserWorkItem(new WaitCallback(processingThread), msg);
}
catch (ApplicationException appEx)
{
sLog = String.Format("[pbx] Exception thrown while creating received
buffer processing thread: " + appEx.Message);
m_maq.log.logWarning(1, sLog);
}
catch (Exception)
{
sLog = String.Format("[pbx] Generic exception thrown while creating
received buffer processing thread");
m_maq.log.logWarning(1, sLog);
}
------------------------

It works just fine, and I think that this way I achieve my goal: receiving
and processing are not coupled.

BUT it is the first time I use the ThreadPool, and I'm quite new to C# (I'm
arriving from C++), so I would like to ask you if you think I'm using
ThreadPool the right way, if you think that this usage could end up with
some other problem or serious inconvenience, and to ask you for hints and
advices.

Thank you!

Ricardo Vázquez.
Madrid, Spain.



Oct 23 '07 #1
6 1617
Hi,
--
Ignacio Machin
http://www.laceupsolutions.com
Mobile & warehouse Solutions.
"Ricardo Vazquez" <rv******@dummy.comwrote in message
news:eZ****************@TK2MSFTNGP04.phx.gbl...
Hello everybody,

I'm programming a TCP server.
During the stress tests I noticed that maybe my socket-receiving thread
became deaf after an hour of heavy stress.
You should have a thread just to receive new connections, once a connection
is received a new thread is created and that thread is the one that handle
that connection. This allows you to receive new incomming calls.

The "worker thread" can either use async or sync request. I think it depends
of what are you transfering.
I think that the reason could be this: The processing of the received
messages. Something goes wrong in this processing and the code gets stuck
here. As the processing is within the receiving "while" loop, the loop
gets
also stuck, so that we will never reach again the Socket.Receive invoke;
thereafter we are deaf.
Using the above you will never get deaf. The server will always answer.
Besides I disliked the idea of processing the message within the receiving
loop. Somehow I understand that receving should be more "disconnected"
from
the rest of the code.
It depends, in my code the receiving is sync and therefore is inside the
loop. You can decoople it if your scenario allows it.
Just take into account that it will make the code more difficult to
maintain/read.
Oct 23 '07 #2
Hi Ignacio!

Thank you very much for your advice and interest!

Kind regards,

Ricardo.
>I'm programming a TCP server.
During the stress tests I noticed that maybe my socket-receiving thread
became deaf after an hour of heavy stress.

You should have a thread just to receive new connections, once a
connection is received a new thread is created and that thread is the one
that handle that connection. This allows you to receive new incomming
calls.

The "worker thread" can either use async or sync request. I think it
depends of what are you transfering.
You are right, of course. But I already have this:
A thread listening for connections.
When a new client connects I get a new socket, and I create a new client
object with it; somthing like this:
------------------------------------
while(!m_stopServer)
{
try
{
clientSocket = m_server.AcceptSocket();
socketListener = new ClientThread(m_maq, clientSocket);
lock(clients.SyncRoot)
{
clients[socketListener.ClientSocket] = socketListener;
}
socketListener.StartSocketListener();
}
catch ... etc.
...
}
------------------------------------
But, as you see, the new client starts a receiving thread:
socketListener.StartSocketListener().
This is the thread I was talking about, the one that got stuck after one
hour of stress testing, the one I was trying to de-couple: the
client-instance receiving thread.


Oct 23 '07 #3
Ricardo Vazquez wrote:
Hello everybody,

I'm programming a TCP server.
During the stress tests I noticed that maybe my socket-receiving thread
became deaf after an hour of heavy stress.
I think that the reason could be this: The processing of the received
messages. Something goes wrong in this processing and the code gets stuck
here. As the processing is within the receiving "while" loop, the loop gets
also stuck, so that we will never reach again the Socket.Receive invoke;
thereafter we are deaf.

Besides I disliked the idea of processing the message within the receiving
loop. Somehow I understand that receving should be more "disconnected" from
the rest of the code.
I think generally that is a good goal, yes.

You really need to post a concise-but-complete sample of code that
reliably reproduces your problem. Showing excerpts is not very useful,
as there's no way to know whether the excerpt includes the problematic
part or not.

On the other hand, posting your complete code is also not very useful,
as that usually results in there being way too much code for someone not
being paid to debug your code to inspect. Thus "concise". Post only
the bare minimum required to reproduce the problem.

Noting, of course, that with networking code there are two ends to every
communication, and you must post both ends for the sample to be truly
usable. A complete sample for one end is better than nothing, but it
won't allow anyone to actually compile and run your code to see what's
going wrong.

Now, all that said: I don't see how using the ThreadPool will help this.
There's a maximum number of threads that the ThreadPool will have, and
so if you've got a bug in which your code is somehow getting stuck, you
will eventually consume all of the ThreadPool threads, as those get
stuck one by one instead of your receiving thread. All you do by using
the ThreadPool is move the problem somewhere else.

It's not possible to say from your post why your code gets stuck.
However, if you are using multiple threads it's likely that you've got a
deadlock bug somewhere. You should use the debugger when your program
gets stuck and see where in each thread it is waiting. If it's a
deadlock problem, you'll have at least two threads waiting on something
that is either directly or indirectly held by the other thread.

You should also consider using the async methods for the Socket class.
If you are looking to take advantage of threading to get the i/o out
into its own code path, the async methods are a great way to accomplish
that. They aren't necessarily going to solve your deadlock problem, but
they will clean up the overall design, and possibly make it easier to
figure out what is deadlocking.

Pete
Oct 23 '07 #4
The reality is that you're not really using the ThreadPool the right way.
For a client app, you would be fine. But for a high-load server, it's not
going to work quite right.

Under stress, you're going to get Thread Pool starvation, and your
application will deadlock.

For a set of very detailed explinations and some suggestions, see:
http://www.coversant.com/Coversant/B...8/Default.aspx
http://www.coversant.com/Coversant/B...0/Default.aspx

--
Chris Mullins

"Ricardo Vazquez" <rv******@dummy.comwrote in message
news:eZ****************@TK2MSFTNGP04.phx.gbl...
Hello everybody,

I'm programming a TCP server.
During the stress tests I noticed that maybe my socket-receiving thread
became deaf after an hour of heavy stress.
I think that the reason could be this: The processing of the received
messages. Something goes wrong in this processing and the code gets stuck
here. As the processing is within the receiving "while" loop, the loop
gets
also stuck, so that we will never reach again the Socket.Receive invoke;
thereafter we are deaf.

Besides I disliked the idea of processing the message within the receiving
loop. Somehow I understand that receving should be more "disconnected"
from
the rest of the code.

So I thought of a different thread, asynchronously processing the received
message.
And, as after heavy stress this thread could get stuck as I said, I
thought
of using the ThreadPool (even though one processing-thread gets stuck, the
following messages will be processed anyway, because ThreadPool will give
us
a new thread to do this).

So, code would be something like this:
------------------------
int nRes = 0;
Byte[] buffer = new Byte[MAX_RECV_SIZE];
try
{
nRes = m_pSocket.Receive(buffer, MAX_RECV_SIZE, SocketFlags.None);
}
catch ...
...
string msg = Encoding.ASCII.GetString(buffer, 0, nRes);
sLog = String.Format("[pbx] CTIServer {0} < recv: '{1}'",
getPbxStringId(), msg);
m_maq.log.logNormal(3, sLog);
try
{
ThreadPool.QueueUserWorkItem(new WaitCallback(processingThread), msg);
}
catch (ApplicationException appEx)
{
sLog = String.Format("[pbx] Exception thrown while creating received
buffer processing thread: " + appEx.Message);
m_maq.log.logWarning(1, sLog);
}
catch (Exception)
{
sLog = String.Format("[pbx] Generic exception thrown while creating
received buffer processing thread");
m_maq.log.logWarning(1, sLog);
}
------------------------

It works just fine, and I think that this way I achieve my goal: receiving
and processing are not coupled.

BUT it is the first time I use the ThreadPool, and I'm quite new to C#
(I'm
arriving from C++), so I would like to ask you if you think I'm using
ThreadPool the right way, if you think that this usage could end up with
some other problem or serious inconvenience, and to ask you for hints and
advices.

Thank you!

Ricardo Vázquez.
Madrid, Spain.



Oct 23 '07 #5
Hi Pete,

Thank you very much for your answer.
You are right: If there is really a deadlock, the usage of 1 thread or 25
threads is not a solution: they will all finally get stuck and nothing was
solved.
I need to debug that possible deadlock, as you said: "You should use the
debugger when your program gets stuck and see where in each thread it is
waiting. If it's a deadlock problem, you'll have at least two threads
waiting on something that is either directly or indirectly held by the other
thread."

But, as I said, I'm new to .net and Visual Studio 2005...

What is it the way to debug a deadlock? Any guidelines, web links,
orientation, detailed explanation...? :-)

Once again, thank you very much!

Ricardo.

Advanced Telephony
Applications --------------------------------------------------------------------------------
[Texto] Ricardo Vázquez Almagro Jusan, s.a. Research & Development Tel: +34
91 456 0110 (ext. 52) Fax: +34 91 553 1411 mailto: rv******@jusan.es web:
www.jusan.es
"Peter Duniho" <Np*********@NnOwSlPiAnMk.comescribió en el mensaje
news:13*************@corp.supernews.com...
Ricardo Vazquez wrote:
>Hello everybody,

I'm programming a TCP server.
During the stress tests I noticed that maybe my socket-receiving thread
became deaf after an hour of heavy stress.
I think that the reason could be this: The processing of the received
messages. Something goes wrong in this processing and the code gets stuck
here. As the processing is within the receiving "while" loop, the loop
gets
also stuck, so that we will never reach again the Socket.Receive invoke;
thereafter we are deaf.

Besides I disliked the idea of processing the message within the
receiving
loop. Somehow I understand that receving should be more "disconnected"
from
the rest of the code.

I think generally that is a good goal, yes.

You really need to post a concise-but-complete sample of code that
reliably reproduces your problem. Showing excerpts is not very useful, as
there's no way to know whether the excerpt includes the problematic part
or not.

On the other hand, posting your complete code is also not very useful, as
that usually results in there being way too much code for someone not
being paid to debug your code to inspect. Thus "concise". Post only the
bare minimum required to reproduce the problem.

Noting, of course, that with networking code there are two ends to every
communication, and you must post both ends for the sample to be truly
usable. A complete sample for one end is better than nothing, but it
won't allow anyone to actually compile and run your code to see what's
going wrong.

Now, all that said: I don't see how using the ThreadPool will help this.
There's a maximum number of threads that the ThreadPool will have, and so
if you've got a bug in which your code is somehow getting stuck, you will
eventually consume all of the ThreadPool threads, as those get stuck one
by one instead of your receiving thread. All you do by using the
ThreadPool is move the problem somewhere else.

It's not possible to say from your post why your code gets stuck. However,
if you are using multiple threads it's likely that you've got a deadlock
bug somewhere. You should use the debugger when your program gets stuck
and see where in each thread it is waiting. If it's a deadlock problem,
you'll have at least two threads waiting on something that is either
directly or indirectly held by the other thread.

You should also consider using the async methods for the Socket class. If
you are looking to take advantage of threading to get the i/o out into its
own code path, the async methods are a great way to accomplish that. They
aren't necessarily going to solve your deadlock problem, but they will
clean up the overall design, and possibly make it easier to figure out
what is deadlocking.

Pete

Oct 24 '07 #6
Ricardo Vazquez wrote:
[...]
But, as I said, I'm new to .net and Visual Studio 2005...

What is it the way to debug a deadlock? Any guidelines, web links,
orientation, detailed explanation...? :-)
First, you'll need to be using a retail version of Visual Studio. It is
possible to debug deadlocks and other threading issues in the Express
version, but it's not something I'd recommend for someone unfamiliar
with the general techniques of dealing with thread issues in the first
place, since Express doesn't provide any direct way to get at the
individual threads in the debugger.

So, assuming you have a retail version of VS, the next step is to run
your application under the debugger until it gets stuck (or attach the
VS debugger to a process running your application after it gets stuck).

At that point, use the Break command to stop execution of your program.
Once the process has been interrupted, you can then use the Threads
drop-down in the Debug toolbar to examine the state of each thread. It
will allow you to switch from one thread to another, with the source
view, stack trace, local variables, etc. being updated according to the
current thread.

Some of the thread will be irrelevant, and may not even include any of
your own code (all of the code in the stack trace will be "external").
You'll be looking for threads that are stopped on a statement that waits
for some resource, to identify which threads are involved in the
deadlock and why they are waiting.

At some point, you should come across at least two threads that are
waiting, each of which are waiting on a different resource, but in each
case a resource being held by some other thread that is also waiting.
That's your deadlock.

Once you've identified that, then you need to figure out what in your
design led to the bug where you have that circular resource acquisition
going on and fix that. Depending on your experience level that in and
of itself could be a challenge, but regardless you need to first
identify the problem for that to even be an option.

Pete
Oct 24 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Phil Powell | last post by:
Ok, I installed ANT, I have c:\ant in my ANT_HOME environment variable, I have c:\ant\bin in my PATH environmental variable, I installed the JAR files for TCL and for Javascript (Rhino)... to no...
12
by: Phil Powell | last post by:
<cfquery name="getAll" datasource="#request.dsn#"> SELECT U.userID, U.fname, U.lname, U.phone, U.lastLoggedIn, U.choiceId, U.experience, T.label AS teamLabel, R.label AS roleLabel FROM User U...
6
by: Serge | last post by:
hi, the framework has the ThreadPool class. Very handy. But as far as I can see this is a singleton (only 1 instance). Does anybody know a way how to have multiple ThreadPools inside a...
6
by: Max Adams | last post by:
Threads and ThreadPool's If I use a ThreadPool how can I tell when a thead in the threadpool has exited? I don't want to set a global member variable I would much rather be able to act on an...
16
by: NOtcarvinSPAM | last post by:
It occurs to me that if I have a work object that gets executed via QueueUserWorkItem AND the work proc accesses only that object's instance data I STILL may have to lock because the object...
5
by: Henri | last post by:
Might sound a stupid question but need to be sure: When you call ThreadPool.QueueUserWorkItem and ThreadPool.RegisterWaitForSingleObject passing a New object as state e.g.:...
1
by: colinjack | last post by:
Hi All, I've been using the original (non-event based) asynchronous design pattern using delegates. It works fine but performance wise I know using the ThreadPool is supposed to be far better,...
3
by: arasub | last post by:
ep 20, 2007 11:25:57 AM org.apache.catalina.core.AprLifecycleListener lifecycleEvent INFO: The Apache Tomcat Native library which allows optimal performance in production environments was not found...
3
by: Steven Blair | last post by:
I have been watching an MSDN video on the PFX Task class and have a question. Here is my scenario: TcpListener waits on incoming connections. Once a new connection is established, a new Task...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.