Strange problem with threads and logic tics.

Hi, I have this situation. I have a module which uses OSC.ThreadingOSCServer. This module creates a thread and execute some callbacks you define on osc requests.

The problem is that I have to connect an always sensor to an empy function for the callbacks to be called. And the sensor’s freq is the frequency the callback is called.


def emptyFunct():
    return #this is connected to the always sensor

def callback()
    ...process OSC # this should be called by the thread when an OSC packet is received, but instead, it is called at the always sensor rate.


If an OSC is sent to blender each 100ms, and I have the always sensor set to 1000ms (for example), the callback is called only once in a second. The strangest of all, is that it works if the always sensor is in any module, in any object, it just has to execute some python code.

So I guess blender doesn’t work well with python threads. Any light on this (monster, wink wink :slight_smile: )

Threads sleep in between logic ticks, so in your case, the callback only executes when the thread wakes up, i.e. every logic tick. The thread can attempt to execute callbacks 10x a second but it’ll only process whichever one happens to coincide.

The alternative is to use polling - check something every frame. Instead of the thread notifying the BGE through callbacks, the BGE (your code) should check with the thread, if it’s possible, like reading from a queue etc. If not, it’d probably be easier to use a socket - have a seperate process send UDP packets to the BGE, and in the BGE try to read data from the non-blocking socket every tick.

But is it a blender or python limitation? I wouldn’t mind if the thread call the callbacks every tic, as I can put the fps higher, but it doesn’t do so. To test it, I have a counter in a function connected to an always sensor, and a counter in the callback. The always one goes a lot faster that the callback. So the callback is not being called every tick.

I do not know the internals of threads and how they run within the Python engine. So I can’t tell you anything about them.

What I can tell is, that it is not a good idea to try to manipulate a scene from a thread. This is because such manipulations need to take place in a specific time window. This is the time when the controllers are executed. Everything else could result in inconsistent states.

Typically you use a thread if you want to decouple one processing (your thread) from other processing (the main process). This means you do not care if it runs faster or slower. I do not see any reason to decouple BGE processing this way. The (pseudo)parallel running controllers and actuators already do that.

You can perform any non-conflicting processing in your own thread - just do not touch the BGE.

The BGE on the other side does not know if your thread produced results since last frame. There is no according sensor [you could develop one, but I guess you do not want to do that]. You can check at each frame if there is a result waiting in the queue = polling … as Mahalin already suggested. When there is nothing … you can skip the further processing. If there is something you take the results from the queue and process them.

I have no information regarding OSC. If it is a good library it should be able to use polling too.
Edit: I think you need SocketServer.UDPServer.

Just my thoughts.

Btw. what do you plan to do in this “callback”?

If an OSC is sent to blender each 100ms, and I have the always sensor set to 1000ms (for example), the callback is called only once in a second.

Maybe I’m missing something, but won’t setting the always sensor to tick every frame solve your issue?

So I guess blender doesn’t work well with python threads. Any light on this (monster, wink wink :slight_smile: )

Blender works fine with threads, if you use them correctly. Threads are a confusing concept, regardless of the engine you are trying to use them with.

Yes, I had it that way, but the thread was being called each logic tic, which doesn’t make any sense. Anyway, now I poll the OSCServer each tic manually, and process all the OSC requests. Much easier now.

Yes, I’m quite used to threads in C/C++, but either python or blender, does something weird with them.

Have a reqd of this:

It’ll explain why threading can work strangely in python, and how to use it properly.
You could also taky a look at this:
https://blenderartists.org/forum/showthread.php?348061-Simple-Multiprocessing-Demo

Thanks for the info!