May 09, 2024, 08:53:16 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Can we have multithreading commands?

Started by kibalab, November 04, 2007, 02:55:03 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

kibalab

Aurora and EBasic are both great and I don't know which one I like best but there is something I miss with both: multithreading support. I know this can be achieved through the WinAPI but I have not that much experience with the WinAPI and it would be nice if EBasic (and Aurora) could have some basic multithreading support.

Thank you!

LarryMc

KiBaLabs
It is not necessary to clutter up the forums with multiple request for the same thing.
I assure you Paul reads the forums AND he can remember what he has read better than most of us.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

kibalab


Ionic Wind Support Team

Is is a question that gets asked a lot.  Creating threads is very simple to do though so i don't know how much easier I can make it that just using the API.  Most people that ask for "threading support" have never bothered to even look to see how it is done.

You only need 4 API declares, 5 if you want to be able to terminate a thread prematurely.  And one constant ;).

'stuff needed for simple multithreading
DECLARE IMPORT,CloseHandle(handle as UINT),INT
DECLARE IMPORT,WaitForSingleObject(handle as UINT,dwMilliseconds as UINT),INT
DECLARE IMPORT,CreateThread(lpThreadAttributes as POINTER,dwStackSize as UINT,lpStartAddress as UINT,lpParameter as POINTER,dwCreationFlags as UINT,lpThreadId as UINT ByRef),UINT
DECLARE IMPORT,ResumeThread(hThread as UINT),INT
DECLARE IMPORT,TerminateThread(hThread AS UINT,dwExitCode AS INT),INT
CONST CREATE_SUSPENDED = 0x4

A thread, is of course, just a subroutine that gets run as a separate execution point.  It has one parameter, as dictated by Microsoft.

SUB mythread(pParam as pointer)
....do something that is going to take gobs of time
RETURN 0
ENDSUB

The parameter is a pointer to whatever you want to pass the thread function and is specified in the CreateThread lpParameter variable.   I normally use a UDT just to pass stuff back and forth.

TYPE mydata
   int result
ENDTYPE

def md as mydata
md.result = 0

Then you tell windows to start the thread, and use the handle returned to see if it is still executing.  Check the handle to make sure it isn't 0

UINT hThread
INT temp
hThread = CreateThread(NULL, 0, &mythread, &md, CREATE_SUSPENDED, temp)
IF hThread <> 0
   ResumeThread(hThread)
   WHILE WaitForSingleObject(hThread, 100) <> 0
           ...do something else here while the thread is still running
   ENDWHILE
   CloseHandle(hThread)
ENDIF

WaitForSingleObject is a general purpose API function.  In this case it waits for the thread to terminate, checking it every 100 ms. 

That is the basics of it.  Feel free to look at the MSDN site (or search google) for more examples.  The above code can be adapted for just about any purpose. 

Then again you have to ask yourself what you need mutithreading for.   If it is just to remain responsive in a GUI app while you are processing then just inserting a WAIT 1 statement in your loops will keep everything working.

Paul.
Ionic Wind Support Team

kibalab

Thank you Paul. I had a look at the WinAPI helpfile yesterday and figured out the functions (also looking at the windows.inc file) but not how to use them. Your example is a great help and I think itwould be a good idea to have stuff like that in the WinAPI section of the helpfile.
I need multithreading for a program that takes a number and calculates wheter it's a chaotiv number, a tidy number or a prime (don't worry if you can't find something about that topic in the internet, it's a theory I hypothesized). It's a problem that can be easily parallelised (hope that's right, I'm not a native English speaker as you may have already guessed) and would easily benefit from multithreading.

John Syl.

Paul,
Thanks, you make is sound so easy.

I've been playing with multi-threading for some time now (in Aurora) but used a the CThread class created by Mike Stefanik, I could never get my head round the use of the API  but with that simple explanation, I think it cleared a lot of the mystery up.  Many thanks.

John
Intel 3.6 p4 ht, XP home,2 gb mem, 400 gb hd 20gb raid 0, Nvidia 6600le.
AMD k6-2 500, 40gb.

Started on PDP11 Assembler, BASIC, GWBASIC, 6502, Z80, 80x86, Java, Pascal, C, C++, 
IBasic (std & pro), Aurora, EBasic.  (Master of none, but it's been fun!)

kibalab

Thanks to Pauls short tut I have written a small function. Here it is with a sample, use as you like:

' EasyThread
' by Sebastian Erben
' basti@kibalabs.com
'
' Licensed under the LGPL!

DECLARE IMPORT,CreateThread (lpThreadAttributes AS POINTER,dwStackSize AS UINT,lpStartAddress AS UINT,lpParameter AS POINTER,dwCreationFlags AS UINT,lpThreadId AS UINT BYREF),UINT
DECLARE IMPORT,ResumeThread (hThread AS UINT),WORD
DECLARE IMPORT,CloseHandle (handle AS UINT),WORD

SUB ET_Thread(subAsThread AS UINT,subParam AS POINTER)

DEF threadHandle AS UINT
DEF tmpHandle AS UINT

threadHandle = CreateThread(0,0,subAsThread,subParam,0x4,tmpHandle)

IF threadHandle <> 0 THEN ResumeThread(threadHandle)

CloseHandle(threadHandle)

ENDSUB

'THE HELPER FUNCTION ENDS HERE!
'THE SAMPLE STARTS HERE!

SUB Thread1(param AS POINTER)

DEF countA AS UINT
countA = 0

DO
PRINT("This is Thread 1")
countA += 1
UNTIL countA = 10

ENDSUB

SUB Thread2(param AS POINTER)

DEF countB AS UINT
countB = 0

DO
PRINT("This is Thread 2")
countB += 1
UNTIL countB = 10

ENDSUB

OPENCONSOLE
DEF myParam AS INT
myParam = 0

ET_Thread(&Thread1,&myParam)
ET_Thread(&Thread2,&myParam)

DO
UNTIL INKEY$ <> ""
CLOSECONSOLE
END

kibalab

Sry for doublepost:

It is very important that you are sure your threads are terminating! If one of you extends the above stuff (for example with TerminateThread(), SuspendThread(), Mutex etc.) then please post the updated version (LGPL license) so we all benefit from it :)