I am running a short bit of code that will occasionally (very rarely) Access Violate on the Terminate/Free of my TThread. I am running many instances of these threads but this spot seems to be the only ones that is causing problems and it only does so once every 500 or so calls.
TThreadInheritor* Base= new TThreadInheritor(1);
try {
Base->Start();
WaitForSingleObject((HANDLE)Base->Handle, 1000);
MyBaseId = Base->scanvalue;
}__finally {
Base->Terminate();
Base->Free();
}
It is being开发者_运维百科 thrown in my finally. My first guess was that WaitForSingleObject was timing out in a weird way and causing the Terminate and Free to mess up, but I'm not quite sure how that would happen. I didn't change anything to do with the Terminate/Free methods when I inherited from TThread.
Anyone know what could cause those two methods to access violate after so little code?
Never free a TThread
that is still running. The base class TThread
destructor is not safe in that regard. It does some pretty stupid things that can cause problems. ALWAYS make sure a TThread
is fully terminated before freeing it. Use the WaitFor()
method, or wait until WaitForSingleObject()
reports WAIT_OBJECT_0
.
Firstly, do not use Base->Free()
. Use delete Base;
instead.
More importantly, you should call Base->WaitFor()
after Terminate()
to make sure it is actually terminated prior to deleting the object.
Base->Terminate();
Base->WaitFor();
delete Base;
Otherwise you'd be deleting the thread object (which your code / RTL may still be using) prematurely thus leading to the occasional access violation.
Or you could set the FreeOnTerminate
property to true and forget about waiting / deleting the object altogether (be careful about running out of virtual memory though if you have too many threads since there's no 64-bit version of C++ Builder yet).
精彩评论