How to create threads in window
BlitzMax Forums/BlitzMax Programming/How to create threads in window
| ||
I found a way how to create thread in windows: ======== thread.bmx File 1 of 2 ============= Strict Import "win32thread.bmx" Global count:Int = 0 Local funcPtr:Int() = foo Local funcPtr2:Int() = foo2 Local h1:Int = CreateThread(Null,0,funcPtr) Local h2:Int = CreateThread(Null, 0,funcPtr2) While True If count = 10 TerminateThread(h1) Print "" Print "Thread 1 terminates..." Print "" count = 0 End If Wend Function foo() While True Print "Thread Nr. 1 counts: " + count count = count + 1 Delay 750 Wend End Function Function foo2() While True Print "Hallo, I'm thread number 2" Delay 500 Wend End Function ======= win32thread.bmx File 2 of 2 ======= Extern "Win32" Rem The CreateThread function creates a thread to execute within the virtual address space of the calling process. HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); Return Values If the function succeeds, the return value is a handle to the new thread. If the function fails, the return value is NULL. End Rem Function CreateThread:Int (lpThreadAttributes:Byte Ptr,.. 'Pointer to a SECURITY_ATTRIBUTES structure. dwStackSize:Int,.. 'Initial size of the stack, in bytes. pStartAddress:Int(), .. 'Pointer To the application-defined Function To be executed by the thread And represents the starting address of the thread. lpParameter:Byte Ptr=Null,.. ' Pointer to a variable to be passed to the thread. dwCreationFlags:Int=0,.. 'Flags that control the creation of the thread. pThreadId:Int Ptr=Null) 'Pointer to a variable that receives the thread identifier. If this parameter is NULL, the thread identifier is not returned. Rem The TerminateThread function terminates a thread. BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode ); hThread [in, out] Handle to the thread to terminate. dwExitCode [in] Exit code for the thread. Use the GetExitCodeThread function to retrieve a thread's exit value. Return Values If the function succeeds, the return value is nonzero. End Rem Function TerminateThread:Int (hThread:Int, dwExitCode:Int =0) End Extern |
| ||
eek! is that safe... I wouldn't run any gui command in a thread for instance... But I wonder if a loader could fill a bank byte at a time while incrementing a counter, while the main app moved a progress bar... nice work btw! |
| ||
Another example, manipulates GUI. You need win32thread.bmx, from first post. === threadGUI.bmx, File 1 of 1 =========== Strict Import "win32thread.bmx" Global count = 0 Local window:TGadget Global button:TGadget window=CreateWindow("MaxGui Buttons",40,40,240,300,0,WINDOW_TITLEBAR) CreateTimer(1) button=CreateButton("Push Button",10,10,140,24,window,BUTTON_PUSH) Local funcPtr:Int() = changeGUI CreateThread(Null, 0, funcPtr) While True WaitEvent Select EventID() Case EVENT_WINDOWCLOSE End Case EVENT_GADGETACTION Print "EVENT_GADGETACTION" End Select Wend Function changeGUI() While True count = count + 1 SetGadgetText button, count Print count Delay 250 Wend End Function |
| ||
are you *sure* maxGui is thread safe! |
| ||
you dont necessarily need hardware threads to have the appearance that more than one thing is happening at once in your program. You can implement a form of multitasking. |
| ||
Although this might appear to work. I dont think the Garbage Collector in MAX is thread safe. All my testing prior to 1.12 indicates no way to write any useful threading in BMAX. Now maybe Mark can clarify if the memory managment changes have introduced thread safe functionality. I dont see it in the source but thats not to say the compiler isnt emitting it Mutexes to make it work. As for why this works: The method setGadetText ultimatly fails down to a windows API SendMessage to the control. And just to note the Windows GUI api is thread safe. StdIO is also thread safe which is why the print works. Still on the fence on BMAXs ability to write threaded code... Maybe Mark can answer about the BMAX memory manager. Doug Stastny |
| ||
Well according to his latest/2nd latest worklog he has been thinking about threads (altho that's about the extent of it so far I think) - which could indicate the gc revamp has been given a thread-safe approach... I guess the best way to find out (apart from a direct answer from Mark) would be to try things and see if they brake =] |
| ||
Can someone tell me if this is actually safe or not? All(!) I want is a seperate interrupt which sits there, happily updating something (think C64 IRQ's here).. Not having this ability at present really limits Max. If it's not safe, does anyone have any suggestions, other than going the Visual C route? Thanks |
| ||
Can you use CreateProcess? |
| ||
I'm not sure that's the same thing? From my understanding, CreateProcess will run another application. I want a method to allow another thread to run some code, where it will sit and wait in a tight loop for a semaphore or timer before processing.. Or have I missunderstood? |
| ||
I don't know as I don't know what the 'something' is you want updated. As for CreateProcess : I want a method to allow another thread to run some code, OK, it's not a thread but it can run some code. where it will sit and wait in a tight loop for a semaphore or timer before processing.. It can sit and wait on a timer or until it receives a message or data. |
| ||
OK, perhaps I wasn't that clear! What I wanted was a method to allow for an audio update routine to be updated as a background task. The update routine would handle resampling / mixing, before passing the data to a ring buffer for actual playback via the winmm waveOut functions. All pretty simple and basic functionality - as long as I could get another thread active, which would update my audio code. The main point is that the code at the start of this post *should* do this, but the question as to if it is safe or not was never answered from 2 years ago. So, the question remains - is using CreateThread in this manner safe or not? My gut feeling is that its not safe, otherwise i'd also have expected some nice snazzy multi-thread commands to be added to BlitzMax. Just would really like some clafication. Thanks JP |
| ||
You could run other code in a different thread no problems, as long as it wasn't BlitzMax code - so something like c/c++ etc would work fine. But if you wanted that code to call back into BlitzMax and have it do something while your BlitzMax code was already busy doing something else, there's a good chance you might get some problems cropping up. |
| ||
Hmm. Thats what I thought..Shame though...I hoped to use BlitzMax for something a little more than it being essentially just a host for a bunch of DLL's. Out of interest, what problems "might" crop up and why? Is there anything I could do to limit the risk? For example, something like only using local variables in the hope that they're just chucked on the a stack, rather than corrupting RAM? Or would I still eventually be heading towards another brick wall? Thanks, Brucey. |
| ||
According to Skidracer threads are not safe to use with the blitzmax language at all, so you have three options... 1. Do it all in blitzmax without threads (using a timer and hook). 2. Write the entire audio side in C or C++ and extern to the functionality from bmax. 3. Dump bmax and do it all in a different language (C/C++ etc or even PureBasic allows threads). Option 1 you could use winmm+timer+hook, or you could use MaxMod and a custom TMusic object (directsound and openal support), both will have latency issues. Option 2 is what I've ended up using for my DJ application, and I'm also having to rewrite MaxMod and my Tracker project also, but it is less cpu intensive, very low latency and for some reason sounds better :/ and as a nice side effect adding VST support is made 100% easier. If this is just for a game I'd take option 1, but if you're doing something more audiophile related then option 2 or 3 is the best way to go (as I've found out after YEARS of trial and error). *EDITED* |
| ||
Option 2 it is then. Thanks for the response, REDi. JP |
| ||
FreeBasic also had thread support. It would be nice to be able to use threads in BM though :( |