Delphi thread creation error

delphi thread creation error

www.codenewsfast.com › cnf › article. Posted: Tue Aug 02, 2011 1:18 pm Post subject: Delphi Thread DLL creating error inject process the problem and the following dll and inject. And yes I KNOW that there is plenty of RAM (4Gigabyte) and PLENTY disk space (24*80GB). Is there some kind of setting I can set either in Delphi.

Delphi thread creation error - really


"> I have a class that is used for logging and it uses threading (so as not to
> disrupt the flow of the main program).

OK
> During testing I get this error on a seemingly random basis when I attempt to > create the thread: > "Thread creation error: Not enough storage is available to process this > command." > It's of the EThread error class type.

Never seen this. I use threaded loggers, and many threads for other purposes, & have never encountered this error.
> The actual code: > constructor TLogThread.Create(aFilename, aSectionName, aValue: String); > begin > FreeOnTerminate := True; > FFileName := aFileName; > FName := aSectionName; > FValue := aValue; > inherited Create(False); <--------Error Occurs Here > end;

Well, I'm not happy about setting the 'FreeOnTerminate' property on an object that does not exist. Try:
 constructor TLogThread.Create(aFilename, aSectionName, aValue: String);  begin   inherited create(true);   FreeOnTerminate := True;   FFileName := aFileName;   FName := aSectionName;   FValue := aValue;   resume;  end;
Rgds, Martin

Board index » delphi » TIdSMTP raises Thread creation error, help!!!

Thanks for your reply, Remy
The TIdSMTP is created in the thread, and after email send completed, the
TIdSMTP will be freed, and will be created again if a new email will be
sent. In this case, can I add a TIdAntiFreeze in it? And where do I create
it? Can I create it in the thread?
Thanks
"Remy Lebeau (TeamB)" <[email protected]>дÈëÏûÏ¢ÐÂÎÅ:45bdac[email protected]

Quote

"David" <[email protected]>writes
news:[email protected]

>the Connect produce will create thread?

Yes, it does. That is the only way to implement the ConnectTimeout
functionality for a blocking socket. The actual connection is opened
in a worker thread, while Connect() keeps track of the elapsed time.
If it takes too long, Connect() closes the socket. The thread is then
killed regardless of whether the connection succeeded or failed.

The only way to bypass the thread is to set ConnectTimeout to 0, and
not use a TIdAntiFreeze component. If ConnectTimeout is not 0, or
TIdAntiFreeze is used, then the thread is created.


Gambit


 


CreateThread function (processthreadsapi.h)

  • Article
  • 5 minutes to read

Creates a thread to execute within the virtual address space of the calling process.

To create a thread that runs in the virtual address space of another process, use the CreateRemoteThread function.

Syntax

Parameters

A pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpThreadAttributes is NULL, the handle cannot be inherited.

The lpSecurityDescriptor member of the structure specifies a security descriptor for the new thread. If lpThreadAttributes is NULL, the thread gets a default security descriptor. The ACLs in the default security descriptor for a thread come from the primary token of the creator.

The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is zero, the new thread uses the default size for the executable. For more information, see Thread Stack Size.

A pointer to the application-defined function to be executed by the thread. This pointer represents the starting address of the thread. For more information on the thread function, see ThreadProc.

A pointer to a variable to be passed to the thread.

The flags that control the creation of the thread.

ValueMeaning
0
The thread runs immediately after creation.
CREATE_SUSPENDED
0x00000004
The thread is created in a suspended state, and does not run until the ResumeThread function is called.
STACK_SIZE_PARAM_IS_A_RESERVATION
0x00010000
The dwStackSize parameter specifies the initial reserve size of the stack. If this flag is not specified, dwStackSize specifies the commit size.

A pointer to a variable that receives the thread identifier. If this parameter is NULL, the thread identifier is not returned.

Return value

If the function succeeds, the return value is a handle to the new thread.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Note that CreateThread may succeed even if lpStartAddress points to data, code, or is not accessible. If the start address is invalid when the thread runs, an exception occurs, and the thread terminates. Thread termination due to a invalid start address is handled as an error exit for the thread's process. This behavior is similar to the asynchronous nature of CreateProcess, where the process is created even if it refers to invalid or missing dynamic-link libraries (DLLs).

The number of threads a process can create is limited by the available virtual memory. By default, every thread has one megabyte of stack space. Therefore, you can create at most 2,048 threads. If you reduce the default stack size, you can create more threads. However, your application will have better performance if you create one thread per processor and build queues of requests for which the application maintains the context information. A thread would process all requests in a queue before processing requests in the next queue.

The new thread handle is created with the THREAD_ALL_ACCESS access right. If a security descriptor is not provided when the thread is created, a default security descriptor is constructed for the new thread using the primary token of the process that is creating the thread. When a caller attempts to access the thread with the OpenThread function, the effective token of the caller is evaluated against this security descriptor to grant or deny access.

The newly created thread has full access rights to itself when calling the GetCurrentThread function.

Windows Server 2003:  The thread's access rights to itself are computed by evaluating the primary token of the process in which the thread was created against the default security descriptor constructed for the thread. If the thread is created in a remote process, the primary token of the remote process is used. As a result, the newly created thread may have reduced access rights to itself when calling GetCurrentThread. Some access rights including THREAD_SET_THREAD_TOKEN and THREAD_GET_CONTEXT may not be present, leading to unexpected failures. For this reason, creating a thread while impersonating another user is not recommended.

If the thread is created in a runnable state (that is, if the CREATE_SUSPENDED flag is not used), the thread can start running before CreateThread returns and, in particular, before the caller receives the handle and identifier of the created thread.

The thread execution begins at the function specified by the lpStartAddress parameter. If this function returns, the DWORD return value is used to terminate the thread in an implicit call to the ExitThread function. Use the GetExitCodeThread function to get the thread's return value.

The thread is created with a thread priority of THREAD_PRIORITY_NORMAL. Use the GetThreadPriority and SetThreadPriority functions to get and set the priority value of a thread.

When a thread terminates, the thread object attains a signaled state, satisfying any threads that were waiting on the object.

The thread object remains in the system until the thread has terminated and all handles to it have been closed through a call to CloseHandle.

The ExitProcess, ExitThread, CreateThread, CreateRemoteThread functions, and a process that is starting (as the result of a call by CreateProcess) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means that the following restrictions hold:

  • During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.
  • Only one thread in a process can be in a DLL initialization or detach routine at a time.
  • ExitProcess does not complete until there are no threads in their DLL initialization or detach routines.
A thread in an executable that calls the C run-time library (CRT) should use the _beginthreadexand _endthreadexfunctions for thread management rather than CreateThreadand ExitThread; this requires the use of the multithreaded version of the CRT. If a thread created using CreateThreadcalls the CRT, the CRT may terminate the process in low-memory conditions.

Windows Phone 8.1: This function is supported for Windows Phone Store apps on Windows Phone 8.1 and later.

Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows Server 2012 R2, and later.

Examples

For an example, see Creating Threads.

Requirements

Minimum supported clientWindows XP [desktop apps

TThreadPriority (Delphi)

This example shows how to create a thread and start it running at a lower priority than the main execution thread. Set the thread's FreeOnTerminate property to True, so that there is no need to free the thread when it finishes. The Execute procedure must be overridden in the extension class of TThread or else an "Abstract Error" will result. To create the extension, choose the File > New > Other > Thread Object menu.

procedureTForm1.Button1Click(Sender:TObject);beginif(mythreadRunning=False)thenbeginmythreadRunning:=True;MyProcess:=TMyThread.Create(True);{ Create suspended-second process does not run yet. }MyProcess.FreeOnTerminate:=True;{ You do not need to clean up after termination. }MyProcess.Priority:=tpLower;{ Set the priority to lower than normal. }MyProcess.Resume;{ now run the thread }endelseMessageDlg('This thread is still running. You are going to hurt yourself!',mtInformation,[mbOk],0);end;procedureTForm1.Button4Click(Sender:TObject);beginifmythreadRunningthenMyProcess.Terminate();end;procedureTMyThread.Execute;varI:Integer;beginForm1.Memo1.Lines.Add('Process has been running for this many seconds:');forI:=0to10dobeginifTerminatedthenbreak;Form1.Memo1.Lines.Add('Low priority process '+InttoStr(I));Sleep(1000);end;mythreadRunning:=False;end;procedureTYouThread.Execute;varI:Integer;beginForm1.Memo3.Lines.Add('Second low priority process has been running for this many seconds:');forI:=0to10dobeginifTerminatedthenbreak;Form1.Memo3.Lines.Add('Second low priority process '+InttoStr(I));Sleep(1000);end;youthreadRunning:=False;end;procedureTForm1.Button2Click(Sender:TObject);varI:Integer;beginForm1.Memo2.Lines.Add('Do some work in the main process for 10 seconds:');forI:=0to10dobeginForm1.Memo2.Lines.Add('Main process '+InttoStr(I));Sleep(1000);end;end;procedureTForm1.Button3Click(Sender:TObject);beginif(youthreadRunning=False)thenbeginyouthreadRunning:=True;YouProcess:=TYouThread.Create(True);{ Create suspended-second process does not run yet. }YouProcess.FreeOnTerminate:=True;{ You do not need to clean up after termination. }YouProcess.Priority:=tpLower;{ Set the priority to lower than normal. }YouProcess.Resume;{ Now run the thread. }endelseMessageDlg('This thread is still running. You are going to hurt yourself!',mtInformation,[mbOk],0);end;procedureTForm1.Button5Click(Sender:TObject);beginifyouthreadRunningthenYouProcess.Terminate();end;procedureTForm1.FormCreate(Sender:TObject);beginmythreadRunning:=False;youthreadRunning:=False;end;

Cast thread error or terminate thread can free resource

Jackie Chang's profile photo

Jackie Chang

unread,
Mar 15, 2008, 7:49:11 PM3/15/08

Reply to author

Sign in to reply to author

Forward

Sign in to forward

Delete

Link

Report message as abuse

Sign in to report message as abuse

Show original message

Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message

to

{ TMyThread }
procedure TMyThread.Execute;
var
StrList: TStringList;
begin
StrList:= TStringList.Create;
try
while (1=1) do
sleep(1000); {I need cast error from Main From! }
finally
StrList.Free;
end;
end;

Cast thread error from Main From! It's possible?
Or terminate thread can run finally section? How?

Thx!

Peter Below (TeamB)'s profile photo

Peter Below (TeamB)

unread,
Mar 16, 2008, 1:00:37 PM3/16/08

Reply to author

Sign in to reply to author

Forward

Sign in to forward

Delete

Link

Report message as abuse

Sign in to report message as abuse

Show original message

Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message

to

Jackie Chang wrote:

You cannot force an exception to be raised inside a thread from outside
the thread.

What you need is a different design for your wait loop. Wait on an
event object (TSimpleEvent) to become signalled, perhaps with a
timeout. The object can then be signalled from outside the thread to
make the wait wake up before the timeout expires.

The following thread class is an example of this design. It contains
some stuff not relevant to the problem, so don't get distracted <g>.

type
{: This class implements a thread that can be managed by the thread
pool. It can also be used outside the pool, however, if it is
managed
by an instance of the TThreadManager class.}
TPoolThread = class(TThread)
private
FIdle: Boolean;
FNext: TPoolThread;
FOnThreadDying: TNotifyEvent;
FQueue: IInterfaceList;
FSignal: TSimpleEvent;
FStandalone: Boolean;
procedure RepoolThread;
procedure RunTasks;
procedure WaitForWork;
protected
procedure DoThreadDying;
procedure Execute; override;
property Standalone: Boolean read FStandalone;
public
constructor Create(AStandalone: Boolean = false); reintroduce;
destructor Destroy; override;
procedure Die;
function Hook(NewNext: TPoolThread): TPoolThread;
procedure SubmitTask(const aExecutor: IExecutor);
function Unhook: TPoolThread;
property Idle: Boolean read FIdle;
property Next: TPoolThread read FNext;
property OnThreadDying: TNotifyEvent read FOnThreadDying write
FOnThreadDying;
end;

{: A worker thread will usually be part of a thread pool (aStandalone =
false) but it can also be used in isolation (aStandalone = true). In
the latter case it will not repool itself when a task completes. <br>
The worker thread has an internal task queue and a signal on which it
will wait while the queue is empty. The thread will self-destruct when
it terminates.}
constructor TPoolThread.Create(AStandalone: Boolean = false);
begin
inherited Create(true);
FreeOnTerminate := true;
FSignal := TSimpleEvent.Create;
FQueue := TInterfaceList.Create;
FIdle := true;
FStandalone := AStandalone;
Resume;
end;

destructor TPoolThread.Destroy;
begin
FreeAndNil(FSignal);
FQueue := nil;
inherited Destroy;
end;

{: Terminates and sets the thread up for destruction}
procedure TPoolThread.Die;
begin
Terminate;
try
FSignal.SetEvent;
except on EAccessViolation do
{There is a very slight chance that the thread has already self-
destructed when we try to set the signal. That could result in
an access violation. Ignore that here. }
end;
end;

{: The OnThreadDying even fires in the context of the thread! If you
need an event fired in
the main threads context use OnTerminate, but keep in mind that this
will only work in a VCL GUI app! }
procedure TPoolThread.DoThreadDying;
begin
if Assigned(FOnThreadDying) then FOnThreadDying(Self);
end;

{: Repeat to wait for tasks and execute them until the thread is
terminated. Any exceptions will be trapped and logged, but they
will terminate the thread. A notification event is fired before the
thread ends up in the Great Bit Bucket Beyond. Note that the tasks
are responsible to trap and handle execptions in their execution, so
the thread itself will not get terminated by those errors. }
procedure TPoolThread.Execute;
const
SSeparator = ': ';
begin
try
while not Terminated do begin
WaitForWork;
if not Terminated then
RunTasks;
if not (Terminated or StandAlone) then
RepoolThread;
end; {if}
except
on E: Exception do
LogManager.Log(E.ClassName + SSeparator+E.Message);
end;
DoThreadDying;
end;

{: Sets the Next property to the passed value and returns the old
value of Next}
function TPoolThread.Hook(NewNext: TPoolThread): TPoolThread;
begin
Result := TPoolThread(InterlockedExchangeObject(FNext, NewNext));
end;

{: Set the threads state to idle and tell the pool manager that the
thread is available for work.}
procedure TPoolThread.RepoolThread;
var
Temp: IThreadPool;
begin
FIdle := true;
Temp := InternalThreadPool;
if Assigned(Temp) and not Terminated then
(Temp as IThreadPoolManager).AddThread(Self);
end;

{: Execute tasks from the queue until the queue runs dry or the thread
is terminated. }
procedure TPoolThread.RunTasks;
var
Intf: IInterface;
begin
repeat
Intf := FQueue.First;
FQueue.Delete(0);
(Intf as IExecutor).Execute;
until (FQueue.Count = 0) or Terminated;
end;

{: Adds the passed task to the threads queue and wakes the thread.}
procedure TPoolThread.SubmitTask(const aExecutor: IExecutor);
begin
Assert(Assigned(aExecutor));
FIdle := false;
FQueue.Add(aExecutor as IInterface);
FSignal.SetEvent;
end;

{: Set the Next property to nil and returns its old value}
function TPoolThread.Unhook: TPoolThread;
begin
Result := TPoolThread(InterlockedExchangeObject(FNext, nil));
end;

procedure TPoolThread.WaitForWork;
begin
FSignal.WaitFor(INFINITE);
FSignal.ResetEvent;
end;

--
Peter Below (TeamB)
Don't be a vampire (http://slash7.com/pages/vampires),
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com

Jackie Chang's profile photo

Jackie Chang

unread,
Mar 17, 2008, 1:25:55 PM3/17/08

Reply to author

Sign in to reply to author

Forward

Sign in to forward

Delete

Link

Report message as abuse

Sign in to report message as abuse

Show original message

Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message

to

Thanks!

I use Thread to connect database, for some reason, It's may be talk a long
time! The user can break connect!

{ TMyThread }
procedure TMyThread.Execute;
begin
SqlConn.Connected:= True;
end;

SqlExpr.pas
-----------------------------------------
procedure TSQLConnection.DoConnect;
begin
...
LoginParams := TWideStringList.Create;
...
try
...
{ connect database }
FDBXConnection := ConnectionFactory.GetConnection(ConnectionProps);
{ Its may be talk a long time }

finally
FreeAndNil(MemoryConnectionFactory); // If allocated, free it.
SetCursor(DefaultCursor);
LoginParams.Free;
ConnectionProps.Free;
if ConnectionState = csStateConnecting then // an exception occurred
begin
ConnectionState := csStateClosed;
if Assigned(FDBXConnection) then
FreeAndNil(FDBXConnection)
end;
end;
end;
-----------------------------------------
1.TerminateThread(MyThread.Handle, 1);
Cast memory leak!
2.Wait MyThread destroy. That must wait connect finish!

I can not solve my program!, I hope Delphi have ThreadTerminateException :)

Jackie

Remy Lebeau (TeamB)'s profile photo

Remy Lebeau (TeamB)

unread,
Mar 17, 2008, 10:07:24 PM3/17/08

Reply to author

Sign in to reply to author

Forward

Sign in to forward

Delete

You do not have permission to delete messages in this group

Link

Report message as abuse

Sign in to report message as abuse

Show original message

Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message

to


"Jackie Chang" <[email protected]> wrote in message
news:[email protected]

> while (1=1) do

You shold be using the thread's Terminated property instead:

while (not Terminated) do

Then your main thread can call the worker thread's Terminate() method when
needed:

MyThread := TMyThread.Create(False);
//...
MyThread.Terminate;


Gambit

Remy Lebeau (TeamB)'s profile photo

Remy Lebeau (TeamB)

unread,
Mar 17, 2008, 10:11:21 PM3/17/08

Reply to author

Sign in to reply to author

Forward

Sign in to forward

Delete

You do not have permission to delete messages in this group

Link

Report message as abuse

Sign in to report message as abuse

Show original message

Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message

to


"Jackie Chang" <[email protected]> wrote in message

news:[email protected]

> I use Thread to connect database, for some reason, It's may be talk a long
> time! The user can break connect!

If the connection is taking a long time to finish, the only ways to force
the thread to terminate prematurely is to either destroy the DB object from
memory (likely resulting in access violations), or use the Win32 API
TerminateThread() function (likely resulting in resource leaks).

> 1.TerminateThread(MyThread.Handle, 1);
> Cast memory leak!

That will likely cause leaks, yes. You are performing a brute-force
termination that ends the thread immediately, not allowing it to perform any
cleanup operations for itself.

> 2.Wait MyThread destroy. That must wait connect finish!

Yes, because it waits for the thread to be terminated first.

> I can not solve my program!, I hope Delphi have ThreadTerminateException
> :)

It does not. Even if it did, itwould not solve your problem anyway.

Gambit

Peter Below (TeamB)'s profile photo

Peter Below (TeamB)

unread,
Mar 17, 2008, 10:45:07 PM3/17/08

Reply to author

Sign in to reply to author

Forward

Sign in to forward

Delete

Link

Report message as abuse

Sign in to report message as abuse

Show original message

Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message

to

Jackie Chang wrote:

> Thanks!
>
> I use Thread to connect database, for some reason, It's may be talk a
> long time! The user can break connect!

If the database engine itself does not support canceling a running
query from another thread then you simply cannot do this without
causing problems of some kind. The best option is to simply forget the
thread and let it run. If it ever comes back from the query, ignore the
results.

Jackie Chang's profile photo

Jackie Chang

unread,
Mar 18, 2008, 9:34:01 PM3/18/08

Reply to author

Sign in to reply to author

Forward

Sign in to forward

Delete

Link

Report message as abuse

Sign in to report message as abuse

Show original message

Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message

to

"Remy Lebeau (TeamB)" <[email protected]> wrote in message
news:[email protected]


>> I can not solve my program!, I hope Delphi have ThreadTerminateException
>> :)
>
> It does not. Even if it did, itwould not solve your problem anyway.

------------------------------------------------


{ TMyThread }
procedure TMyThread.Execute;
var
StrList: TStringList;
begin
StrList:= TStringList.Create;
try

DoSomeLongTimeProcess(StrList); // catch ThreadTerminateException
finally
StrList.Free;
end;
end;
------------------------------------------------
If thread can catch ThreadTerminateException that cast from OS?
If does have. Its can do perform cleanup operations for itself.
I google to found ThreadAbortException; but it's not for Delphi.
Normality; Most program cleanup operations run quickly,
MainForm can wait for the thread to be terminated.

Jackie Chang's profile photo

Jackie Chang

unread,
Mar 18, 2008, 9:40:22 PM3/18/08

Reply to author

Sign in to reply to author

Forward

Sign in to forward

Delete

Link

Report message as abuse

Sign in to report message as abuse

Show original message

Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message

to

"Peter Below (TeamB)" <[email protected]> wrote in message
news:[email protected]


> If the database engine itself does not support canceling a running
> query from another thread then you simply cannot do this without
> causing problems of some kind. The best option is to simply forget the
> thread and let it run. If it ever comes back from the query, ignore the
> results.

I can't do that! It's application first connect. Not a query.

Jackie

Peter Below (TeamB)'s profile photo

Peter Below (TeamB)

unread,
Mar 18, 2008, 11:13:45 PM3/18/08

Reply to author

Sign in to reply to author

Forward

Sign in to forward

Delete

Link

Report message as abuse

Sign in to report message as abuse

Show original message

Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message

to

Jackie Chang wrote:

Then just give the user a message if the thread does not connect inside
x minutes and then terminate the application *without* trying to free
the thread. There's simply nothing else you can do here.

Remy Lebeau (TeamB)'s profile photo

Remy Lebeau (TeamB)

unread,
Mar 18, 2008, 11:35:55 PM3/18/08

Reply to author

Sign in to reply to author

Forward

Sign in to forward

Delete

You do not have permission to delete messages in this group

Link

Report message as abuse

Sign in to report message as abuse

Show original message

Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message

to


"Jackie Chang" <[email protected]> wrote in message

news:[email protected]

> If thread can catch ThreadTerminateException that cast from OS?

As I told you earlier, there is no such exception available from the OS.
There is no way for one thread to throw an exception in the context of
another thread. Exceptions are always local to the thread that is throwing
and catching them. In the example you showed, the only way to get an
exception in the thread is if DoSomeLongTimeProcess() itself throws one on
its own, such as if another thread destroys resources that
DoSomeLongTimeProcess() is using.

> I google to found ThreadAbortException; but it's not for Delphi.

That is specific to .NET only. There is nothing like that in native
languages.


Gambit

Remarkable, rather: Delphi thread creation error

Delphi thread creation error
CROME ERROR 102
JAVA LANG ERROR
Delphi thread creation error

watch the thematic video

Delphi Thread.avi

0 Comments

Leave a Comment

Proudly Powered By WordPress.

Theme Kaira by .