Thread, Process and Game Loop

It’s seems that if we create a new thread in a module that is called by a controller, the game loop is stopped until the thread is finished.
Could you confirm this ?
Is there another way to create a multithreading system functional with controller ?

SOLUTION (edit 03-13-14):
Threads that are created by a controller seems to be “active” only during the time that the controller is alive, and at the end (when quit) !
module multiprocessing is the solution. I’ve tested it, it is a good alternative, and it continues to make his job, Thread not.

I haven’t tried recently. But they run parallel. Sometimes they do not even get stopped after the BGE finished.

Be aware the BGE is not thread save. So avoid to manipulate the scene from a thread (reading is fine/writing is dangerous).

can i ask what is the advantage of run stuff multithread?

LibLoad is BGE.
The BGE is not multithreaded.

So this will not work. As I wrote do not manipulate the scene.

As you know LibLoad can run asynchron already.
This does not mean, that it will not eat resources when running. If the loading is too processing intensive it will slow down everything incl. the BGE.

The benefit is, you can have a sort-of parallel processing. You can encapsulate processing. E.g you start a heavy calculation and later on you look if it is done. In the meantime you can do something else.

More important, you solve dependency to external sources. E.g. checking for network traffic. Rather than to wait of constantly checking, the thread can wait, while the main process does something else (e.g. showing a progress bar).

The main problem is: There is no guarantied process flow. This makes the code very hard to test. There can be conflicts when sharing resources. There can be deadlocks …

It sounds very cool at the first sight, but adds a complete new layer of potential problems. In worst case the processing is slower then single threaded.

I can’t to do a progress bar running while execute async libload :S

You can do a progress bar.

As far as I know LibLoad does not provide useful progress information (at least not the last time I checked … which is quite a while ago). You still can do an animated hourglass if you like.

benicourt’s problem is that asynch loading makes his game lagging, if I understand him right.

@p9ablo : I’ve tested also and my progress bar will function only if i use libload more that one time, and in different interation of BGE cycles.
The first time i call the controller python, libload obj1
The second time i call the controller python, libload obj2

Another use: make a calculation that is > 1/50s (> logic cycle)

@Monster: Yes Monster, it’s that. My suggestion is: libload async is a C function which use C Threads. Could’nt we add a parameter (priority) to have a libload that dont swallow up all the ressources ? We can do that with C Threads

There are several areas where a python managed c thread could help,
But to take advantage of this, we need to only effect things unseen by the game loop,

Use a c thread to load only unseen areas of the map and unload unseen areas.

Is Kupomans LOD. On its own thread?

You could have the player start in a “barren” area and as he moves out, LOD will load everything for you :smiley:

Does Kupoman LOD keep all of the copies in the ram? Or does it load meshes as it needs them?


yes, for libload i guess will be usefull (i was thinked that it was already working)

PS: one thing like that in the pure logic instead will be a nigtmare :wink:
(ie:-> the sensor “ray” is already… the collision sensor need some minutes instead…wait some cycle :smiley: ;))

A news : Threads that are created by a controller seems to be “active” only during the time that the controller is alive, and at the end (when quit) !

If a have a controller that make a task(n).
First time : I call the controller, it make task(0) … and when the controller end, task(0) is freezed
Second time : I call the controller, it make task(1) … and when the controller end, task(1) is freezed
Third time : I call the controller, it make task(2) … and when the controller end, task(2) is freezed
I Quit:
task(0), task(1) and task(2) continue until end in // mode ! But not during the BGE.
It’s seems that it’s impossible to make multithreading during BGE (with Thread), by the BGE !

Could you confirm that ?

multiprocessing is the solution. I’ve tested it, it is a good alternative, and it continues to make his job, Thread not.

The libload can provide usefull information for make a progress bar, see the KX_LibLoadStatus class, you can use the “progress” variable of the last class.

Threading works for me in the engine. Also, libload status doesn’t give you much useful information from the progress value, due to its implementation

Sent from my Nexus 5 using Tapatalk

@agoose77 : i was thinking too but it wasn’t true.
Try a simple example:
When you press a key, launch a thread that do that sort of thing:

for x in range(0,50):
   print (x)

And you’ll see that the thread won’t function in // mode under blender
But with multiprocessing, it’s functionning.
The new problem is that process is different, so memory has been forked, but they are different after… no liaison

Sleep stops gil in his tracks ?

python can only have 1 gil right?

@BluePrintRandom : Yes with Thread, but with multiprocessing, you fork the process in another process, so 2 GILs (or more 1 per process)!
The problem : global variables aren’t shared after fork - you must use Shared Memory (multiprocessing module has that sort of functions), it’s not implicit

So anything that Gil 2 does, needs to be mixed in or replace a variable/property?

how do you mix them to have a intended result?

In forked process, you must not modify Game Properties or anything else.
You can modify vars that are shared (in shared memory) with the original process.

I haven’t had this problem. Check my threads class for an example

execution is in handle_task ?

By default you subclass this, and the handling code is placed in handle_task. It’s a simple wrapper around a queue interface. You can choose not to use a queue by overriding get_task and returning what you wish from it. handle_task handles the result of get_task and is also provided with the out_queue to use.