Board index » cppbuilder » difference between Main Thread of VCL application and CreateThread

difference between Main Thread of VCL application and CreateThread

Hello,
what is the difference between the main thread of an VCL application and a
thread, created by CreateThread.

I'm using Indy clients, which create Threads for each connection. There is a
problem, when I call Paint method of an owner drawn object at first by main
thread (paint call from system) and second from above mentioned thread,
there is a difference:

main thread works always, if necessary Indy-thread is interrupted.

1st step, peint method encasulated by a criticalsection, result: main thread
ignores criticalsection when set by Indy thread, other way round works.
2nd step replace TCriticalsection by integer variable and "while
 FMyCriticalSection ) Sleep( 50 ): result: main thread sometimes interrupts
indy thread and then waits on that loop, without restarting indy trhead.

Any hints, I'm looking for a solution already for three days
Thx, Christian

 

Re:difference between Main Thread of VCL application and CreateThread


Quote
"Christian Lotze" <_chrissi...@hotmail.com> wrote in message

news:b5pn8f$dqs$01$1@news.t-online.com...

Quote
> what is the difference between the main thread of an VCL
> application and a thread, created by CreateThread.

For starters, they are separate threads.  All processes, whether VCL or
otherwise, have a main thread that is started by the OS itself for the
process to begin with.  Then CreateThread() starts a new secondary thread
that runs in the context of the same process, but is a completely separate
and individual execution thread.

Quote
> I'm using Indy clients, which create Threads for each connection.
> There is a problem, when I call Paint method of an owner drawn
> object at first by main thread (paint call from system) and second
> from above mentioned thread, there is a difference:

You can't use VCL objects across threads without calling the thread class's
Synchronize() method first.  The VCL is not thread-safe, for the most part,
and as such most VCL objects need to run in the context of the main thread
always, not a secondary thread.  That is especially true of visual objects,
as they usually rely on the main message queue to handle the drawing.  What
your secondary thread can do, though, instead of calling Paint() directly,
is to just Invalidate() the object instead, and let it redraw itself
normally in the context of the main thread at the system's own leasure.

Gambit

Re:difference between Main Thread of VCL application and CreateThread


Thanks for answer,
my problem is, that Im calling some functions directly sometimes from main
thead and sometimes from another thread (generated by indy-clients, as
described)and there TCriticalSection and TEvent don't work as I supposed. I
don't have an Problem with VCL calls.
Detailed: I wrote an graphic control and I wan't to lock modify of
appearance (called from main thread, my own function) against adding new
data (called from "indy thread", also my own function) and vice versa.

I have inserted TCriticalSection->Enter and ..->Leave at both functions,
but....
Called from Main thread TCriticalSection does not work! Thread is definitely
not blocked until end of other function.
I found out, that this is normal (you can't use CriticalSection against your
own thread), so I tried a simple integer "semaphore" like

while( locked ) Sleep(50);
locked = 1;
..
locked=0;

But, if main thread runs into that "semaphore", it blocks!

So I have to use another thread for interaction with control, so that there
are two discrete and equal righted threads..

Is that correct?

Thanks, Christian
(PS paint problem was not the main problem, but same reason, I've solved it
by exiting paint, when I'm accessing control from my own thread for
repainting, but I will test your suggestion with Invalidate..)

<Remy Lebeau (TeamB)> schrieb/wrote:

Quote
> "Christian Lotze" <_chrissi...@hotmail.com> wrote in message
> news:b5pn8f$dqs$01$1@news.t-online.com...

>> what is the difference between the main thread of an VCL
>> application and a thread, created by CreateThread.

> For starters, they are separate threads.  All processes, whether VCL
> or otherwise, have a main thread that is started by the OS itself for
> the process to begin with.  Then CreateThread() starts a new
> secondary thread that runs in the context of the same process, but is
> a completely separate and individual execution thread.

>> I'm using Indy clients, which create Threads for each connection.
>> There is a problem, when I call Paint method of an owner drawn
>> object at first by main thread (paint call from system) and second
>> from above mentioned thread, there is a difference:

> You can't use VCL objects across threads without calling the thread
> class's Synchronize() method first.  The VCL is not thread-safe, for
> the most part, and as such most VCL objects need to run in the
> context of the main thread always, not a secondary thread.  That is
> especially true of visual objects, as they usually rely on the main
> message queue to handle the drawing.  What your secondary thread can
> do, though, instead of calling Paint() directly, is to just
> Invalidate() the object instead, and let it redraw itself normally in
> the context of the main thread at the system's own leasure.

> Gambit

Re:difference between Main Thread of VCL application and CreateThread


Quote
"Christian Lotze" <_chrissi...@hotmail.com> wrote in message

news:b5rh99$j01$05$1@news.t-online.com...

Quote
> I have inserted TCriticalSection->Enter and ..->Leave
> at both functions, but.... Called from Main thread
> TCriticalSection does not work!

Yes, it does.  It does not discriminate between which thread is calling it.
Is it possible that you are simply calling your function from the same
thread that already has the lock on the TCriticalSection?

Quote
> you can't use CriticalSection against your own thread

Of course you can.  Where did you hear otherwise?

Gambit

Re:difference between Main Thread of VCL application and CreateThread


<Remy Lebeau (TeamB)> schrieb/wrote:

Quote
> "Christian Lotze" <_chrissi...@hotmail.com> wrote in message
> news:b5rh99$j01$05$1@news.t-online.com...

>> I have inserted TCriticalSection->Enter and ..->Leave
>> at both functions, but.... Called from Main thread
>> TCriticalSection does not work!

> Yes, it does.  It does not discriminate between which thread is
> calling it. Is it possible that you are simply calling your function
> from the same thread that already has the lock on the
> TCriticalSection?

no, different Threads, checked in call stack of different threads an also by
some debug outputs to a special protocol window, one function is called by
indy thread, other function is called by main thread (useraction!), similar
symptom with TEvent: both functions encapsulated with:

MyEvent->WaitFor(10000);
MyEvent->ResetEvent();
...
MyEvent->SetEvent();

in that case the indy thread calls such a function, MyEvent is reset. User
Action calls other function, MyEvent waits (correct) for exactly 10 seconds
(other function needs normaly some milliseconds), runs in TimeOut, function
is executed. Then the first function is completed. I excpected a short wait
while first function completes..

Quote
>> you can't use CriticalSection against your own thread

> Of course you can.  Where did you hear otherwise?

don't remeber, any developer Newsgroup/forum I've searched last days ;-(

Quote

> Gambit

I think, I'm doing something wrong, but not sure where
BTW: your Invalidate tip works fine...

Thx Christian

Re:difference between Main Thread of VCL application and CreateThread


Hello,
after little more testing, Problem is nearly solved :-) I suppose, it was
the direct call to Paint method. Now I have some flickering during repaint,
but I think, I will solve this...

Thanks for your help, Christian

PS Remaining TEvent problem is another one (wrong usage at that place ;-(  )
, I mixed to problems, because of TEvent in both functions.

Re:difference between Main Thread of VCL application and CreateThread


Quote
"Christian Lotze" <_chrissi...@hotmail.com> wrote in message

news:b5rnfr$ape$02$1@news.t-online.com...

Quote
> no, different Threads, checked in call stack of different threads
> an also by some debug outputs to a special protocol window,
> one function is called by indy thread, other function is called by
> main thread

Then, the only other possibility I can think of is if your thread code
calling Enter() is called in the context of a Synchronize() so that the code
is actually run in the main thread instead, and if the main thread already
has the lock, the Enter() returns immediately.  The same scenerio would
effect TEvent::WaitFor() as well.

In general, if a thread already has ownership of a lock on a synchronization
object (event, critical section, mutex, etc), and the same thread tries to
obtain the lock again, it will succeed immediately as such objects do not
block a thread that already has a lock, otherwise the thread would deadlock
itself.  You can't base your assumptions on the fact that your code happens
to be part of another class that wraps a thread internally.  You have to
look at how the code is actually being executed to begin with.

It would really help if you would post your ACTUAL source code for people to
look at.  All of your descriptions indicate that you're actually calling
your code in the context of the same thread, not different threads.

Gambit

Re:difference between Main Thread of VCL application and CreateThread


Thanks for help,
as written in other answer, it was an problem, calling VCL from another
thread, since i removed the paint call from the other function, everything
works fine.
the source code contains some functions of some 100 kb, I don't want to
post. (essence is tho function using Criticalsection, one is called from
vcl, other is called from another thread, but at this position, thread is
not known, cause these functions are functions in my general display
object!)

Essential core was Main Thread and another Thread, generated by Indy clients
are calling my own display object, one was adding data an doing a paint call
afterwards, other was modifying properties and doing a paint call. That was
the problem. I tried to use CriticalSection and TEvent, but the problem was
VCL, not a real thread problem.
now I'm calling InvalidateRect from both function and system (Main Thread)
calls paint afterwards, everything ist fine.

Thanks again for help.
Christian

<Remy Lebeau (TeamB)> schrieb/wrote:

Quote
> "Christian Lotze" <_chrissi...@hotmail.com> wrote in message
> news:b5rnfr$ape$02$1@news.t-online.com...

>> no, different Threads, checked in call stack of different threads
>> an also by some debug outputs to a special protocol window,
>> one function is called by indy thread, other function is called by
>> main thread

> Then, the only other possibility I can think of is if your thread code
> calling Enter() is called in the context of a Synchronize() so that
> the code is actually run in the main thread instead, and if the main
> thread already has the lock, the Enter() returns immediately.  The
> same scenerio would effect TEvent::WaitFor() as well.

> In general, if a thread already has ownership of a lock on a
> synchronization object (event, critical section, mutex, etc), and the
> same thread tries to obtain the lock again, it will succeed
> immediately as such objects do not block a thread that already has a
> lock, otherwise the thread would deadlock itself.  You can't base
> your assumptions on the fact that your code happens to be part of
> another class that wraps a thread internally.  You have to look at
> how the code is actually being executed to begin with.

> It would really help if you would post your ACTUAL source code for
> people to look at.  All of your descriptions indicate that you're
> actually calling your code in the context of the same thread, not
> different threads.

> Gambit

Other Threads