Hello,
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 ?
Greg
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.
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.
@MarcoIt:
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.
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.
Example:
The first time i call the controller python, libload obj1
The second time i call the controller python, libload obj2
etc.
@MarcoIT:
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,
Solution?
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
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
(ie:-> the sensor “ray” is already… the collision sensor need some minutes instead…wait some cycle ;))
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.
@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)
sleep(1)
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
@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
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.
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.