Page 1 of 2
For those who like making threaded programs but...
Posted: Mon Jun 19, 2006 8:41 pm
by dracflamloc
Code updated For 5.20+
This little tidbit of code can be used to operate similar to threads without the risk and overhead of being thread-safe. Good for 3.94 and doing games and dx interaction as well. Easily converted to pb4...
Code: Select all
Structure TASK_INFO
function.l
lastTimeMs.l
delayMs.l
autoremove.b
parameter.l
useParam.b
EndStructure
Global NewList TaskList.TASK_INFO()
Procedure RegisterTask(*func,delay.l,autoremove.b)
AddElement(TaskList())
TaskList()\function=*func
TaskList()\delayms=delay
TaskList()\lastTimeMs=ElapsedMilliseconds()-1
TaskList()\autoremove=autoremove
EndProcedure
Procedure RegisterTaskEx(*func,delay.l,autoremove.b,parameter.l)
AddElement(TaskList())
TaskList()\function=*func
TaskList()\delayms=delay
TaskList()\lastTimeMs=ElapsedMilliseconds()-1
TaskList()\parameter=parameter
TaskList()\useparam=1
TaskList()\autoremove=autoremove
EndProcedure
Procedure RunTasks(nowMs.l)
ForEach TaskList()
If nowMs - TaskList()\lastTimeMs >= TaskList()\delayMs
If TaskList()\UseParam
CallFunctionFast(TaskList()\function,TaskList()\parameter)
Else
CallFunctionFast(TaskList()\function)
EndIf
TaskList()\lastTimeMs=nowMs
EndIf
Next
ForEach TaskList()
If TaskList()\autoremove And TaskList()\lastTimeMs=nowMs
DeleteElement(TaskList())
EndIf
Next
EndProcedure
Just do: RunTasks(ElapsedMilliseconds()) in your main loop.
Posted: Mon Jun 19, 2006 9:05 pm
by srod
Hey, that's pretty cool!

Nice idea.
Thanks.
Posted: Mon Jun 19, 2006 11:38 pm
by netmaestro
Thanks for sharing, it's a well-thought and well-written piece of code!
Ok, now the downside: The main strength of a thread is that it executes asyncronously, that is it'll do its thing without holding up execution of the main program. For me that's most of why I'd use a thread, and unfortunately the main loop in this approach is going to wait patiently until the CallFunctionFast() has returned before moving on with its desperately-vital tasks, all of which are most certainly crucial to the survival of the planet. (ok maybe not, but they do want to continue while the thread runs)
Posted: Mon Jun 19, 2006 11:50 pm
by Rescator
Actually, tasks aren't truly "async" either.
We are getting closer to that though with dual core or multi cpu setups.
Posted: Tue Jun 20, 2006 9:34 am
by Bonne_den_kule
Nice idea.
Posted: Tue Jun 20, 2006 11:44 am
by dioxin
I'm with Netmaestro on the downside.
Threads are completely different to what you have here.
Your code is treated as a single process by the OS and is given a single timeslice at any time in which to run. All of your "threads" will share that one timeslice.
Real threads are each given their own independant timeslice by the OS and the OS will determine which thread runs and when.
e.g. If one thread accesses data from a file on disk the OS knows that this will take a while so it will immediately suspend that thread and the next thread will run while the disk drive fetches the data. In your case, the CPU will wait until the data is got from the disk, and no other task will run while your function fetches data so the CPU time is lost and the overall program runs more slowly.
without the risk and overhead of being thread-safe
There is no risk to being thread safe and you only need the overhead when its useful, i.e. you choose when to make things thread safe to suit the application.
Paul.
Posted: Tue Jun 20, 2006 12:39 pm
by dracflamloc
can be used to operate similar to threads
I never said they were the same. But they can acheive a similar effect while still allowing thread-like coding. This is because modern CPUs are so fast a smaller task should execute so quickly it appears to be executing like a thread would. Also realize that this actually can be *more* accurate than using a thread loop with a Delay() because Delay() only guarentees that the thread will wait at LEAST that long, so if you delay(10) it might wait 13 or 20 or 30 until the next available time it can get to run.
Use it or don't? :roll:
(Oh and thanks Rescator

)
I was gonna say that but you covered it.
Posted: Tue Jun 20, 2006 12:43 pm
by dracflamloc
Btw I changed the code a bit. (ElapsedMilliseconds-1)
Posted: Tue Jun 20, 2006 1:08 pm
by dioxin
Rescator,
Actually, tasks aren't truly "async" either.
Threads are.
Asynchronous doesn't mean simultaneous. The threads don't run at the exact same time but they do run without regard to the timing of other threads unless you deliberately keep them in sync.
We are getting closer to that though with dual core or multi cpu setups.
The technique shown here will not benefit from multiple CPUs as it still remains a single process and will be tied to a single CPU.
Threads are each created with their own process and can each run on a different CPU if one is available.
Paul.
Posted: Tue Jun 20, 2006 3:22 pm
by dracflamloc
I don't think thats what he meant...
But anyway the whole point of this code was for people who make games in PB and cant use multithreading because of DX and other things. Debate this somewhere else.
Posted: Tue Jun 20, 2006 3:51 pm
by dioxin
Debate this somewhere else.
That would make no sense.
Paul.
Posted: Tue Jun 20, 2006 3:59 pm
by dracflamloc
It makes damn perfect sense. If you want to use this code and have recommendations for changes and features then say so here in this thread. Debating threading and multi-cpu machines does not belong in my tips and tricks thread.
Posted: Tue Jun 20, 2006 4:52 pm
by dioxin
dracflamloc,
your initial post, first line says:
This little tidbit of code can be used to operate similar to threads without the risk and overhead of being thread-safe.
Points which distinguish your approach from true threads are therefore valid since you draw comparisons between your approach and threads. It's perfectly reasonable to also point out the differences.
You imply that threaded code is risky which it isn't (not unless PB has a problem with it that I don't know about).
It would be misleading to not post a discussion here as anyone with less knowledge of the subject could mistakenly come across your code, believe that it performs in a similar way to threaded code and believe that threaded code is risky and may never look into real threads and completely miss out on the advantages that real threaded code gives.
Since the main purpose of this place is to help others I see nothing wrong with helping others reading this to understand the difference between your approach and threaded code. To not do so would be unprofessional.
Debating threading and multi-cpu machines does not belong..
Explaining how your approach differs from threaded code does belong here as you initially draw the comparison yourself.
Multi CPU comments were directed at Rescator who appeared to confusing asynchronous with multi/single CPUs.
Paul.
Posted: Tue Jun 20, 2006 5:01 pm
by dracflamloc
Using threads with strings, linkedlists, sprite libraries, as well as pb's networking commands can cause problems and crashes. I stated the reasons for using this code. I just said it can be used similar to threads. You dont like it thats fine.
And of course, you are the utmost in professionalism.

Posted: Tue Jun 20, 2006 6:19 pm
by netmaestro
@dracflamloc, I like your code and I'm going to use it. I just took a second to point out that it'll still execute non-async and I had no idea it would start anything. Sorry!