Board index » cppbuilder » stop all threads - resume all threads - access violation

stop all threads - resume all threads - access violation


2004-11-02 05:57:26 AM
cppbuilder69
Hello,
i n my application i like to stopp and resume threads. here is my code:
// code for stop
TMyThread *thread;
for (int i = 0; i < MyThreadList->Count; i++)
{
thread = (TMyThread*)MyThreadList->Items[i];
thread->Suspend();
}
delete thread;
// code for resume
TMyThread *thread;
for (int i = 0; i < MyThreadList->Count; i++)
{
thread = (TMyThread*)MyThreadList->Items[i];
thread->Resume();
}
delete thread;
when i stopp all threads an resume then later, i get an access violation. i
think that there will be problems with my "delete thread". how to make my
code fine?
Steffan
 
 

Re:stop all threads - resume all threads - access violation

"Steffan Kahn" < XXXX@XXXXX.COM >writes:
Quote
Hello,

i n my application i like to stopp and resume threads. here is my code:

// code for stop
TMyThread *thread;
for (int i = 0; i < MyThreadList->Count; i++)
{
thread = (TMyThread*)MyThreadList->Items[i];
thread->Suspend();
}
delete thread;
Once deleted, how could you possibly expect to resume it?
Quote
// code for resume
TMyThread *thread;
for (int i = 0; i < MyThreadList->Count; i++)
{
thread = (TMyThread*)MyThreadList->Items[i];
thread->Resume();
}
delete thread;
If you somehow manage to resume a thread successfully, why would you
immediately delete the object out from under it?
The best way to manage TThread objects is to set the "FreeOnTerminate"
property to true, and let them delete themselves once they exit.
Otherwise, if you're going to manually manage the object lifetime, you
should only delete the thread object after the thread that it launched
has terminated. Normally, you would tell the thread to terminate
(which is a request "on your honor" that the thread object respects.
It must query the Terminated property periodically to check if it
should voluntarily shut down.) Once that's done, the main thread
waits on the thread, and after the "waitfor" function returns, then
you can safely delete the object. I recommend, however, having the
object free itself.
--
Chris (TeamB);
 

Re:stop all threads - resume all threads - access violation

"Steffan Kahn" < XXXX@XXXXX.COM >wrote in message
Quote
// code for stop
TMyThread *thread;
for (int i = 0; i < MyThreadList->Count; i++)
{
thread = (TMyThread*)MyThreadList->Items[i];
thread->Suspend();
}
delete thread;
Why are you suspending the threads prior to freeing them? Also, you are
only freeing the last thread, and if there are no threads in the list at
all, you are freeing an uninitialized pointer instead.
Quote
// code for resume
TMyThread *thread;
for (int i = 0; i < MyThreadList->Count; i++)
{
thread = (TMyThread*)MyThreadList->Items[i];
thread->Resume();
}
delete thread;
Why are you freeing threads you just resumed?
Quote
when i stopp all threads an resume then later, i get an access violation.
As well you should, because your code logic is faulty. You destroyed some
of your thread instances, but did not update your list to reflect the
deleted threads, so you are later accessing invalid pointers, causing your
AVs.
Quote
i think that there will be problems with my "delete thread".
how to make my code fine?
You should not have those 'delete' statements at all in the code you shown.
Get rid of them.
Gambit
 

{smallsort}

Re:stop all threads - resume all threads - access violation

hi,
my aim was only to stop all threads and later resume all. i didn't want
delete them. so when i kick my "delete thread" it would works?
but then i have create an object which never will be deleted?
steffan
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >schrieb im Newsbeitrag
Quote

"Steffan Kahn" < XXXX@XXXXX.COM >wrote in message
news:4186b152$ XXXX@XXXXX.COM ...

>// code for stop
>TMyThread *thread;
>for (int i = 0; i < MyThreadList->Count; i++)
>{
>thread = (TMyThread*)MyThreadList->Items[i];
>thread->Suspend();
>}
>delete thread;

Why are you suspending the threads prior to freeing them? Also, you are
only freeing the last thread, and if there are no threads in the list at
all, you are freeing an uninitialized pointer instead.

>// code for resume
>TMyThread *thread;
>for (int i = 0; i < MyThreadList->Count; i++)
>{
>thread = (TMyThread*)MyThreadList->Items[i];
>thread->Resume();
>}
>delete thread;

Why are you freeing threads you just resumed?

>when i stopp all threads an resume then later, i get an access
violation.

As well you should, because your code logic is faulty. You destroyed some
of your thread instances, but did not update your list to reflect the
deleted threads, so you are later accessing invalid pointers, causing your
AVs.

>i think that there will be problems with my "delete thread".
>how to make my code fine?

You should not have those 'delete' statements at all in the code you
shown.
Get rid of them.


Gambit


 

Re:stop all threads - resume all threads - access violation

Steffan Kahn wrote:
Quote
hi,

my aim was only to stop all threads and later resume all. i didn't want
delete them. so when i kick my "delete thread" it would works?

but then i have create an object which never will be deleted?

steffan
Please show us where you have created the thread object.
TMyThread *thread;
:
:
thread = (TMyThread*)MyThreadList->Items[i];
doesn't create the thread. So where have you created your thread?
And what are the property settings of the thread?
As Chris pointed out, just set the FreeOnTerminate property true. When the
control falls out of the thread execute loop (typically when the Terminated
property becomes true), the thread object will be deleted.
keith
 

Re:stop all threads - resume all threads - access violation

"Keith" < XXXX@XXXXX.COM >wrote in message
Quote
As Chris pointed out, just set the FreeOnTerminate property true.
When the control falls out of the thread execute loop (typically
when the Terminated property becomes true), the thread object
will be deleted.
The only problem with doing that is you still have to update the list to
remove threads when they terminate, otherwise you still run the risk of
causing AVS from accessing invalid pointers. If you are going to use the
FreeOnTerminate property, then you should also use the thread's OnTerminate
event as well, and use that to remove terminated threads from the list when
needed.
Gambit
 

Re:stop all threads - resume all threads - access violation

"Steffan Kahn" < XXXX@XXXXX.COM >wrote in message
Quote
but then i have create an object which never will be deleted?
It will be if you are deleting it when you are actually done using it.
Gambit
 

Re:stop all threads - resume all threads - access violation

Hi,
i do not want to terminate the thread. i want to hold them and later resume
then.
i create the threads like:
TMyThread *thread = new TMyThread(true);
MyThreadList->Add(thread);
and write each thread into a tlist.
the thread constructor looks like:
__fastcall TMyThread::TMyThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
FreeOnTerminate = true;
...
Suspended = false;
}
so i just want to stop and later resume the threads. as there is noch enable
property i will use the suspend and resume.
to do this i need to read all the threads of my tlist. to read the threads
of my tlist a need a pointer to an TMyThread object. and i learnt, that
everything i create with new, i have to delete later. but i dont want do
delete a thread.
steffen
"Keith" < XXXX@XXXXX.COM >schrieb im Newsbeitrag
Quote


Steffan Kahn wrote:

>hi,
>
>my aim was only to stop all threads and later resume all. i didn't want
>delete them. so when i kick my "delete thread" it would works?
>
>but then i have create an object which never will be deleted?
>
>steffan

Please show us where you have created the thread object.

TMyThread *thread;
:
:
thread = (TMyThread*)MyThreadList->Items[i];

doesn't create the thread. So where have you created your thread?

And what are the property settings of the thread?

As Chris pointed out, just set the FreeOnTerminate property true. When
the
control falls out of the thread execute loop (typically when the
Terminated
property becomes true), the thread object will be deleted.

keith

 

Re:stop all threads - resume all threads - access violation

hi,
this is write, because i will also give my application the opportunity to
delete some threads. i never did before.
i would do like this:
i use a counter so that each thread get its unique id. for this i use the
Tag property. when i want to delete a thread, i am looking for all TMyThread
instances and delete only the one, where the Tag has the id.
is this an elegant way? ich think there might be a problem. when i delete
the thread from the TList from OnTerminate i seems to delete a thread
itself. and a component can't delete itself.
steffen
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >schrieb im Newsbeitrag
Quote

"Keith" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>As Chris pointed out, just set the FreeOnTerminate property true.
>When the control falls out of the thread execute loop (typically
>when the Terminated property becomes true), the thread object
>will be deleted.

The only problem with doing that is you still have to update the list to
remove threads when they terminate, otherwise you still run the risk of
causing AVS from accessing invalid pointers. If you are going to use the
FreeOnTerminate property, then you should also use the thread's
OnTerminate
event as well, and use that to remove terminated threads from the list
when
needed.


Gambit


 

Re:stop all threads - resume all threads - access violation

"Steffan Kahn" < XXXX@XXXXX.COM >wrote in message
Quote
this is write, because i will also give my application
the opportunity to delete some threads.
The FreeOnTerminate property is only good to use when you want to start
threads and then forget about them. If you want to manage the threads
yourself, then you should not use FreeOnTerminate at all.
Quote
ich think there might be a problem. when i delete the thread
from the TList from OnTerminate i seems to delete a thread
itself. and a component can't delete itself.
That is not what I was suggesting. If you use the FreeOnTerminate property,
the thread will automatically free itself after Execute() exits and the
OnTerminate event returns. Use the OnTerminate event just to remove the
thread from your list, nothing else. You don't need to try to free the
thread as well since it is already going to free itself afterwards.
Gambit
 

Re:stop all threads - resume all threads - access violation

"Steffan Kahn" < XXXX@XXXXX.COM >wrote in message
Quote
i learnt, that everything i create with new, i have
to delete later. but i dont want do delete a thread.
You have to delete it eventually when you are finished using it. Whether
you delete it manually yourself, or let FreeOnTerminate do it for you, you
still need to do it some way regardless.
Gambit
 

Re:stop all threads - resume all threads - access violation

Hi,
i just implement to let the user delete some threads. as i use
freeonterminate, i do not really delete the treads but call their Terminate
function and then delete the entry of the tlist. problem is, that i get an
acces violation, but i can't find an error.
// Check if the number is okay
if (MyThreadList->Count - num>= 0)
{
TMyThread *thread;
for (int i = 0; i < num; i++)
{
thread = (TMyThread*)MyThreadList->Items[MyThreadList->Count-1];
thread->Terminate();
MyThreadList->Delete(MyThreadList->Count-1);
}
}
else
{
// No more Threads
Beep();
String text = AnsiString("You can't delete more users as presented");
ShowMessage(text);
}
is there anything wrong?
steffen
"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >schrieb im Newsbeitrag
Quote

"Steffan Kahn" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>this is write, because i will also give my application
>the opportunity to delete some threads.

The FreeOnTerminate property is only good to use when you want to start
threads and then forget about them. If you want to manage the threads
yourself, then you should not use FreeOnTerminate at all.

>ich think there might be a problem. when i delete the thread
>from the TList from OnTerminate i seems to delete a thread
>itself. and a component can't delete itself.

That is not what I was suggesting. If you use the FreeOnTerminate
property,
the thread will automatically free itself after Execute() exits and the
OnTerminate event returns. Use the OnTerminate event just to remove the
thread from your list, nothing else. You don't need to try to free the
thread as well since it is already going to free itself afterwards.


Gambit


 

Re:stop all threads - resume all threads - access violation

"Steffan Kahn" < XXXX@XXXXX.COM >wrote in message
Quote
i just implement to let the user delete some threads. as i use
freeonterminate, i do not really delete the treads but call
their Terminate function and then delete the entry of the tlist.
There is still a problem with that approach. Since a thread can terminate,
and thus be freed, at any time, if you have to access the thread for ANY
reason then you should not use FreeOnTerminate at all, otherwise you risk
the thread disappearing on you while you are trying to access it.
Quote
problem is, that i get an acces violation, but i can't find an error.
Your loop is all wrong. Use this code instead:
if( MyThreadList->Count>0 )
{
TMyThread *thread;
for(int i = MyThreadList->Count-1; i>= 0; --i)
{
thread = (TMyThread*) MyThreadList->Items[i];
thread->Terminate();
MyThreadList->Delete(i);
}
}
Or this:
if( MyThreadList->Count>0 )
{
TMyThread *thread;
for(int i = 0; i < MyThreadList->Count; ++i)
{
thread = (TMyThread*) MyThreadList->Items[i];
thread->Terminate();
}
MyThreadList->Clear();
}
Gambit