Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

API Threads

Posted on 2002-03-31
11
793 Views
Last Modified: 2010-04-04
How can I get a function to run in its own thread using the api thread function 'CreateThread'?

Handle := CreateThread( nil, // no security                                  
                          0,   // the same stack size                          
                          @ThreadFunc, // thread entry point                    
                          @Self,      // parameter to pass to ThreadFunc        
                          CREATE_SUSPENDED,   // always SUSPENDED              
                          FThreadID ); // receive thread ID
0
Comment
Question by:campid
11 Comments
 
LVL 12

Accepted Solution

by:
Lee_Nover earned 50 total points
ID: 6909290
var hThread: THandle;
    hThdID: Cardinal;

procedure ThdProc;
begin
     MessageBox(0, 'This is running in its own thread', 'some caption', mb_OK);
     TerminateThread(hThread, 0);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
     hThread:=CreateThread(nil, 0, @ThdProc, nil, CREATE_SUSPENDED, hThdID);
     if hThread > 0 then
        ResumeThread(hThread);
end;
0
 
LVL 34

Expert Comment

by:Slick812
ID: 6909751
it is better in delphi to use BeginThread instead of CreateThread, See the Delphi Help for some info about this. Here is some code I did for a timer thread with some comments.


function ThreadFunc(Parameter: Pointer): Integer; stdcall;
begin
Result := 0;
while thdTiming do
  begin
  {thdTiming cuts this thread off, it uses a while loop with a
  SleepEx to get a timer interval effect}
  SleepEx(TimerR.Interval, False);
  case TimerR.ID of
    1: if thdTiming then FlipIt;
    {check for thdTiming here also in case it changed
    during SleepEx}
    2: if thdTiming then MoveBall;
    else Break;
    end;
  end;
TimerR.ID := 0;
EndThread(Result);
{ExitThread(Result);}
{no code below EndThread will be executed}
TextOut(FormDC,4, 100, 'Below EndThread, will not show', 15);
end;

procedure TimerStart;
begin
ResumeThread(hThread);
end;

procedure DoThreadTimer(Interval, TimerID: Word);
var
ThreadId: LongWord;
begin
{The interval should be more than 4 or alot of the processor
time cycles are used, if you need an interval less than 5 then
you may want to set the Thread Priority higher with
SetThreadPriority( )}
if TimerR.ID <> 0 then Exit;
{TimerR.ID is set to 0 when the Thread ends, so check for 0
to make sure you don't start a thread if one is still running}
if Interval < 5 then
TimerR.Interval := 5 else
TimerR.Interval := Interval;
TimerR.ID := TimerID;
CloseHandle(hThread);
{since a thread may be created more than once,
you should Close the Handle}

{if you wanted to use more than one thread then you should keep track
of each thread's handle and close it}
hThread := BeginThread(nil, 0, @ThreadFunc, nil, CREATE_SUSPENDED, ThreadId);
{BeginThread( ) is a Delphi System function which does the same as
windows CreateThread( ), except it sets the global IsMultiThread
variable, thereby making the heap thread-safe. Below is the CreateThread( )
function, which will also work. You need to Start the thread with ResumeThread( )}

{hThread := CreateThread(
        NIL,                        // no security attributes
        0,                           // use default stack size
        @ThreadFunc,                  // thread function
        nil,                // argument to thread function
        0,                           // use default creation flags
        ThreadId);}
       
{SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);}

{use EndThread( ) with BeginThread( ) and use ExitThread( ) with
CreateThread( ), see ThreadFunc( ) above}
end;


- - - - - - - - - -
and here is what the Win32 API Help says about TerminateThread

TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination.

ExitThread may be better for CreateThread, unless you get an out of control thread.
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6910268
he asked :
How can I get a function to run in its own thread using the api thread function 'CreateThread'?
so I replied to that question directly
and yes ExitThread is better ...
but in the case I wrote TerminateThread is also ok cause it's the end of a simple procedure
I actually wanted to add a second post to write about TerminateThread/ExitThread ... but It didn't feel necessary
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 3

Expert Comment

by:vladh
ID: 6911294
listening,..
0
 
LVL 34

Expert Comment

by:Slick812
ID: 6912075
Oh, I guess I should have mentioned that it is best if in your App's OnClose or OnDestroy you can call
CloseHandle(hThread);
to clear the OS thread object.
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6912085
can somebody please tell wtf is this 'listening' thing you all keep posting ???
it's really annoying
0
 
LVL 34

Expert Comment

by:Slick812
ID: 6912134
Lee_Nover, yea the "listening" or "interested" or any other single word comment places that expert on the get Email message for new postings to that question and free access to the question after an answer has been accepted
0
 

Author Comment

by:campid
ID: 6912359
Lee_Nover,

Just what I was looking for. There was me thinking it was going to be a complexed thing.

Thanks to the other guys for your detailed comments but Lee was the first on the seen.


Why were on the topic, is there anyway to create a thread and keep it running after your program terminates?

Cheers, Ian
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6912495
slick tnx :)

campid: no, because when a process terminates it closes all it's spawned threads !

another thing .. you can pass parameters to your function
and this is the more correct implementation
the threadproc should be a function that accepts one pointer parameter and returns integer with stdcall calling convention
and the code :

var hThread: THandle;
   hThdID: Cardinal;

const
 sStr = 'This is running in its own thread'#13#10'launched from thread id: %d - process id: %d';

[code]
type
  PStuff = ^TStuff;
  TStuff = packed record
    p1, p2: Integer;
  end;

function ThdProc(param: pointer): Integer;stdcall;
var lpPar: PStuff;
begin
     Result:=0;
     lpPar:=PStuff(param);
     MessageBox(0, PChar(Format(sStr, [lpPar^.p1, lpPar^.p2])), 'some caption', mb_OK);
     Dispose(lpPar); // we need to free up the memory
     ExitThread(0);
end;

procedure TForm1.Button1Click(Sender: TObject);
var lpPar: PStuff;
begin
     New(lpPar);
     lpPar^.p1:=GetCurrentThreadID;
     lpPar^.p2:=GetCurrentProcessId;
     hThread:=CreateThread(nil, 0, @ThdProc, lpPar, CREATE_SUSPENDED, hThdID);
     if hThread > 0 then
        ResumeThread(hThread);
end;
[/code]
0
 
LVL 34

Expert Comment

by:Slick812
ID: 6914674
you probally should not create a thread with CREATE_SUSPENDED if you do not need to sync it with another thread, I avoid using CREATE_SUSPENDED, if at all posible.
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6915073
yes but you might want to set it's priority prior to runing it :)
or something else :)
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Communication Between RC4 Delphi <-> PHP 3 123
FMX enumerated colours 2 115
how to make 2 step back? ..\..\ ExtractFilePath (paramstr(0)) 5 51
DBCtrlGrid, Delphi, Scroll 7 26
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

860 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question