Threads question

BlitzMax Forums/BlitzMax Programming/Threads question

Oddball(Posted 2012) [#1]
This is my first time using threads in BlitzMax and I was wondering about some best practice. Is it ok to create a background thread at application start up and have it run for the lifetime of the app? Or should I be looking to only keep threads live for as short a time as possible?


dynaman(Posted 2012) [#2]
Either is fine.


Corum(Posted 2012) [#3]
I know that Mac OS needs to execute all the graphics related code inside the main thread.
Do someone can confirm this?


PowerPC603(Posted 2012) [#4]
Windows requires it as well.
I figured that out myself.

I had the main thread doing the rendering, while a separate thread just created 1 sphere every 100ms.

Most of the time it was ok, but sometimes then app just crashed on xRenderWorld (I was using Xors3D engine).
I suppose that was because the main thread was rendering the world while the separate thread was busy creating a sphere, but wasn't completed, and this corrupted some data, resulting in an app crash.


jsp(Posted 2012) [#5]
And as with the graphics it's the same with MaxGUI, use it only from the main thread.
I also start a background thread at application start and then schedule new threads from there. That keeps things separate, which is very important.
Starting and stopping threads add a little overhead, so if that is a problem the thread could go idle until used again.


Oddball(Posted 2012) [#6]
Thanks everybody. I've got threads up and running now. I'm putting together a little something for an event on Sunday. If everything goes well I'll have some pics to show on Monday.


Mahan(Posted 2012) [#7]
Best practices with threads:

1. Keep ALL drawing/GUI in the main thread. (As most ppl already mentioned.)

and equally important:

2. Keep data and state separated between threads and know your "channels".

You can shoot yourself in the foot miserably if you don't think about ownership when you create your data structures.

Channels here mean the places in the code where you transfer data and structures between threads.

(Almost) Never let threads have references to the same data at once, because if they do you (or someone else) will start accessing it simultaneously and this will eventually create bugs that can get very hard to find.

Instead, try to think about passing references and data through channels between threads. When data has left one thread and gone through a channel and arrived in another thread, it should not exist in the first anymore.

I'd strongly recommend thinking of the channels are one-directional, i.e. that the data always leaves one thread and goes to another but not the other way around. If you need the data to be passed back and forth construct two abstract channels, one from A->B and another from B->A. That way you'll more easily be able to avoid (or find) deadlocks i.e. when two threads are waiting for one another at the same time (and everything stops working as consequence).

Avoid race conditions, by not having data or states dependent of other stuff in other threads. Let one piece of data be "self contained" so that independent work can be done on it until it's ready to be passed to another thread (if needed).

If you follow the advise above, interactions between objects (data/structures) can safely be done when both (or more) objects are "owned" simultaneously by a single thread.

If applicable: Create immutable objects (objects that are created in a state that will never change during their lifetime). If an object is immutable, it's usually safe for any number of threads to "own" or "know about it" simultaneously. (Immutability is not 100% supported by blitzmax, but you can create your own conventions for making objects hard to change by accident.)

That's pretty much the highlights of my experience with threads in an OOP/procedural environment.