Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Code Snippets / [DBP] Multithreading in DarkBASIC Professional - Without external plugins

Author
Message
Benjamin
21
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 8th Jan 2008 05:00 Edited at: 11th Jan 2008 23:57
[/b]Multithreading in DarkBASIC Professional

Here are a set of functions to call DLL functions in their own threads, leaving the main thread free for you to operate in while the call is in progress. This is particularly useful for Win API functions such as MessageBox, ChooseColor, and ChooseFont where the application must wait for the user to click something before continuing.

It is also possible to call DBPro functions like this, although you must be very careful about the operations you do while a call is in progress. For example, it is possible to call sync to handle rendering in another thread, but while this is processing you must not make/load any media, or modify any data that rendering uses. You can of course read the position/angle of objects and sprites, but you can't set them. This means you are very limited in what you can do while rendering is in progress, but there are some uses to it. Do not assume that just because the application doesn't crash when you test it, what you are doing is safe. Note that for DBPro functions you should use the cdecl version of the functions, PrepareThreadedDllCallC and CallThreadedDllFunctionC. Here is an example:



You can either set up and call a function in one operation, or prepare a function that you can call multiple times with less overhead. With the latter method the memory allocated for parameter data isn't automatically freed, so you can modify it before each call without having to allocate more memory for it.

When you prepare or make a function call, you pass in a pointer to a block of memory created by make memory that the parameters are passed from. The size of this data specified must be a multiple of 4. Here is an example:



You can then check when the call completes by calling CallIsComplete and passing in the pointer returned by CallThreadedDllFunction. When this function reports the call as complete, you must discard the pointer if you did not prepare the function call. Otherwise, you can reuse it to call the function again.



Note: You must define DLL_KERNEL32 at the top of your code, to specify a DLL number for the functions to use.

Function list

PrepareThreadedDllCall - Prepares a DLL function call that you can use multiple times.
CallThreadedDllFunction - Calls a DLL function in another thread.
PrepareThreadedDllCallC - Identical to PrepareThreadedDllCall, but for cdecl functions.
CallThreadedDllFunctionC - Identical to CallThreadedDllFunction, but for cdecl functions.
ThreadedCall - Calls a function with a previously prepared function call.
CallIsComplete - Checks if the specified call has completed.
GetCallReturnValue - Retrieves the value returned by the call.

Functions



Example 1



Tempest (DBP/DBCe)
Multisync V1 (DBP/DBCe)
Rudolpho
18
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 8th Jan 2008 09:15
This looks interesting, indeed.
I'll give it a go when I get the time.

"I kören hörs de brummande busarna Björnligan och Gondolen"
TechLord
21
Years of Service
User Offline
Joined: 19th Dec 2002
Location: TheGameDevStore.com
Posted: 8th Jan 2008 13:04
Hi Benjamin, as you know I'm working the iCon Winsock lib. I'm still researching how to implement non-blocking sockets. A great deal of the examples on that I've found use multi-threading. This does look very interesting.

Benjamin
21
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 11th Jan 2008 02:34
Glad you guys are interested.

Updated code to allow getting the return value of functions and changed main function to allocate memory with the proper protections.

Tempest (DBP/DBCe)
Multisync V1 (DBP/DBCe)
IanM
Retired Moderator
21
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 11th Jan 2008 14:15
Title fixed to stop this being deleted by a mod.

Roxas
18
Years of Service
User Offline
Joined: 11th Nov 2005
Location: http://forum.thegamecreators.com
Posted: 11th Jan 2008 14:40
Hmm this is really intresting.. Could this make rendering faster too?


Click For Details!
Benjamin
21
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 11th Jan 2008 17:48 Edited at: 11th Jan 2008 17:50
Quote: "Title fixed to stop this being deleted by a mod."

Thanks, I wasn't really sure if it was necessary as the title did already indicate which version of DB this was for.

Quote: "Could this make rendering faster too?"

If you can find something useful/safe to do while rendering is happening, you can improve the speed of the main loop in some cases. The actual rendering will be the same speed though.

Tempest (DBP/DBCe)
Multisync V1 (DBP/DBCe)
Roxas
18
Years of Service
User Offline
Joined: 11th Nov 2005
Location: http://forum.thegamecreators.com
Posted: 11th Jan 2008 18:07
Quote: "If you can find something useful/safe to do while rendering is happening, you can improve the speed of the main loop in some cases. The actual rendering will be the same speed though."


I see.. We should do a list of save things what you could do while threading a certain call and so on..

Just an idea.


Click For Details!
jasonhtml
20
Years of Service
User Offline
Joined: 20th Mar 2004
Location: OC, California, USA
Posted: 12th Jan 2008 22:26
very nice!

Ian T
21
Years of Service
User Offline
Joined: 12th Sep 2002
Location: Around
Posted: 22nd Jan 2008 17:35
Fantastic. Would there be any adverse effects to using this in conjunction with things that plug in to the DBP engine directly, e.g. IanM's file access DLLs?
Benjamin
21
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 24th Jan 2008 15:46 Edited at: 24th Jan 2008 15:51
Quote: "Would there be any adverse effects to using this in conjunction with things that plug in to the DBP engine directly, e.g. IanM's file access DLLs?"

As long as they don't modify any of the internals of DBP, there should be no problem. If you do a threaded SYNC call and try to load some file data simultaneously, there should be no problem (even if using the built-in commands), because rendering only accesses certain data. The rule is that one thread must not write to the same memory that another thread reads/writes with at the same time. As long as the operations obey this rule, there should be no problems.

Quote: "I see.. We should do a list of save things what you could do while threading a certain call and so on.."

Perhaps, it's just a case of noting the most useful things that you can do. After all, there is a fair bit that you can do, but not so much of it will benefit from being threaded.

KISTech
16
Years of Service
User Offline
Joined: 8th Feb 2008
Location: Aloha, Oregon
Posted: 10th Feb 2008 19:54
I can see this being very useful on a dedicated server.

Possibly make a thread for sending update packets to the clients, or using a thread when a database record needs to be updated. Which would keep the main loop free for processing AI and receiving packets from the clients.
KISTech
16
Years of Service
User Offline
Joined: 8th Feb 2008
Location: Aloha, Oregon
Posted: 3rd Mar 2008 18:21
@Benjamin,

Could you possibly give an example of how this would be used to do something simple like a FOR NEXT loop. I'm thinking there are caluclations that can be performed at regular intervals in the background that wont have an impact on data being used in the main loop.

Say for example, something that might slow down a main loop on a server considerably is distance calculations. So if we create a thread that performs these and then grab the resulting data when it's done that should help server performance.

So if I wanted to run the following in a separate thread...



How would I go about doing that?


It's a big universe, and they are out there somewhere.
Benjamin
21
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 4th Mar 2008 11:04
I think the only way to do something like that would be to put it in a function, and have an external TPC execute that function in another thread. Unfortunately this isn't entirely safe, as DBP does some stuff behind the scenes that isn't safe to do from other threads.

Roxas
18
Years of Service
User Offline
Joined: 11th Nov 2005
Location: http://forum.thegamecreators.com
Posted: 4th Mar 2008 14:12
You could use Torreys free multithreading plugin what does what benjamin said.. But you must make all action safe like benjamin said!


Click For Details!
KISTech
16
Years of Service
User Offline
Joined: 8th Feb 2008
Location: Aloha, Oregon
Posted: 4th Mar 2008 20:01
So if I wrote a function in DBPro that performed a file transfer using Multisync and wanted to run that in a separate thread so it wouldn't stop the main loop, would that be something that could be done safely?


It's a big universe, and they are out there somewhere.
MoomanFL
18
Years of Service
User Offline
Joined: 12th Nov 2005
Location:
Posted: 6th Mar 2008 03:53
One way to avoid problems with changing data during a threaded SYNC call is to make a bThreadLock boolean (name can be anything, it is the usage that is important). Have any functions that modify needed data, or load/delete media, check for this before executing the code.

Immediately before you call the thread, just set the boolean to true, and set it to false when the thread action is done.

Design documents?!? What design documents??? I thought we were just going to wing it!!!
Benjamin
21
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 7th Mar 2008 20:12
Quote: "So if I wrote a function in DBPro that performed a file transfer using Multisync and wanted to run that in a separate thread so it wouldn't stop the main loop, would that be something that could be done safely?"

Not entirely. If an error occurs while this thread is executing, the program won't terminate properly and will crash instead.

KISTech
16
Years of Service
User Offline
Joined: 8th Feb 2008
Location: Aloha, Oregon
Posted: 8th Mar 2008 20:34
It also occured to me that Multisync might not be very agreeable to being used in a thread to send a file to a player, when it's also being used to send packets to other players from the main thread. Then there is the complication of it sending the file to the player in a thread, and the main thread then tries to send a game packet to the player at the same time.


It's a big universe, and they are out there somewhere.
wh1sp3r
20
Years of Service
User Offline
Joined: 28th Sep 2003
Location: Czech republic
Posted: 23rd Mar 2008 13:10
Benjamin : interesting

please, how can I make threaded call, for example



So, if you understand, I would like to call function, and program will continue without waiting, until this function end. I can check, if function is done, after that, I can call this function again. Can be this done ? Thank you


PS: Real programmers aren't afraid of math!.
Roxas
18
Years of Service
User Offline
Joined: 11th Nov 2005
Location: http://forum.thegamecreators.com
Posted: 25th Mar 2008 21:38
Like i said torreys multithreaded plugin..

Your signature has been erased by a mod because it was too big
calcyman
16
Years of Service
User Offline
Joined: 31st Aug 2007
Location: The Uncertainty Principle
Posted: 18th Apr 2008 21:20
Is "multithreading" running 2 operations simultaneously? I thought that that was impossible to do, since the CPU can only do one thing at a time.

The optomist's right, The pessimist's right.
Benjamin
21
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 19th Apr 2008 00:30
Quote: "Is "multithreading" running 2 operations simultaneously?"

Yes, it's running multiple threads simultaneously.

Quote: "I thought that that was impossible to do, since the CPU can only do one thing at a time."

The CPU alternates between the threads very fast. If there are multiple CPUs then threads can truly be executed simultaneously.

Login to post a reply

Server time is: 2024-05-10 02:13:03
Your offset time is: 2024-05-10 02:13:03