Newsgroups : Borland : borland.public.delphi.internet.winsock : 2007 Jan : Re: AThreads and Thread manager..

www.cryer.info
Managed Newsgroup Archive

Re: AThreads and Thread manager..

Subject:Re: AThreads and Thread manager..
Posted by:"Remy Lebeau (TeamB)" (no.spam@no.spam.com)
Date:Fri, 5 Jan 2007 17:36:15

"Turboz" <turboz@turboz.moved.in> wrote in message
news:459eec3f$1@newsgroups.borland.com...

> Well, to cut a long story short, yes I am using just one CS in
> the entire server app for all TIdTCPServer threads.

Well, stop it. That is a major bottleneck that will prevent your code
from scaling upwards to handle larger amounts of clients, not to
mention that the more clients that are actually connected at one time,
the slower they will all perform exponentially.  Critical sections are
meant to be used for small lock/query-set/unlock operations only.
Keep them as small as possible, generally to specific blocks of that
directly access shared memory/data and nothing else.  Do not lock
entire operations at all.  Do not lock larger sections of code that
are not actually shared across threads.

> As I understood it, a CriticalSection was designed to stop multiple
> threads accessing shared memory at the same time

That is not how you are actualy using it, though.  You are locking the
entire OnExecute code, which is very bad.

> If I use one CriticalSection for each client (IE, one in each
thread)
> then how does that protect these shared items?

If you actually study the code I gave you earlier, you will see how.
You should not be using 1 critical section to lock all resources at
the same time.  You should be locking each individual resource
separately on a per-needed basis.  That generally means using a
separate critical section for each resource that needs protecting.  In
the code I gave you, each user's thread pointer needs protecting,
which means giving each user its own critical section.

> I noticed in the code you posted for me, that you were creating
> a CS in each 'User'

Correct.

> Surely if each one has it's own CS that defeats the point of the
object

No, it does not.  It allows each object to be responsible for its own
localized thread safety.  You are trying to do it on a global scale
instead, using too few locks, and that is the wrong way to use
critical sections in the first place.

> because multiple clients can gain access to and modify the same
> shared memory at the same time?

No, they cannot.  Each user has its own memory that needs protecting
separately from any other user's memory.  That is why each user has
its own critical section.

Here is an example for you.

Say the server has 5 users connected, A through E.  If user A wants to
send a message to user B, then user B has to be locked in order to
prevent multiple messages from overlapping, and to prevent sending
while disconnecting.  No other users need to be locked by user A, as
user A is not sending anything to them.  Now lets say that user D
wants to send a message to user E at the same time.  There is no
reason for user A to touch user E's lock, and no reason for user D to
touch user B's lock.  User B's lock should be handled completely
separately from user E's lock.  Since the two messages are going to
different destinations, they can be transmitted simultaneously without
interferring with each other.  Now, let's say that user C wants to
send a message to user E as well.  Again, there is no reason for user
C to touch user B's lock at all.  However, since user D is already
sending a message to user E, user C has to wait for user E to be
unlocked before then locking user E to send its own message.  Lastly,
let's say that user E wants to send its own message to user A at the
same time that user D is sending to user E.  Since noone is sending to
user A at the time, user E can lock user A and send a message without
waiting on anyone else.

Now, let's apply the same example using a single global lock instead.

User A sends a message to user B, so the lock is obtained.  While that
is happening, user D wants to send a message to user E, but has to
wait for the lock to be released first.  Once released, then user D
can obtain the lock and send a message to user E.  The two messages
cannot be sent simultanously anymore.  Then user C has to wait for the
lock to be released before sending its own message to user E.  Also,
when user E wants to send a message to uer A, it has to wait for user
D or user C to release the lock first, depending on who gets the lock
first (which then leads to thread switching, timing, and starvation
issues).

Does that make more sense for you?  Since each individual user is
accessed on a per-needed basis, each user should have its own lock.
This allows more messages to be send simultaneous when they are going
to separate destinations, and thus makes better use of the power of
threads.


Gambit

Replies:

In response to:

www.cryer.info
Managed Newsgroup Archive