Thread Safety with bpy API

So I cant find much info on this, therefore, have to ask - is there any information about thread safety when using bpy API? I use image load and raw processing on pixels and on mesh data/bones. Obviously I understand basic issues like operating on the same mesh from different threads, that is no what I’m talking about. I’m talking about the API logic itself and how it operates i.e. for example, in .NET Random just returns an integer value so nothing seems complex but under the hood it is not thread safe:

Instead of instantiating individual Random objects, we recommend that you create a single Random instance to generate all the random numbers needed by your app. However, Random objects are not thread safe. If your app calls Random methods from multiple threads, you must use a synchronization object to ensure that only one thread can access the random number generator at a time. If you don't ensure that the Random object is accessed in a thread-safe way, calls to methods that return random numbers return 0.

I wont have any issues finding info about python, its toolset/eco-system and its quirks, but blender and bpy is another deal.

The bpy API is not thread safe.

The article you’ve linked explains basic 101 threading and not particularly good example in the context of thread-safety I’m talking about. Through their supported example is interesting:

 bpy.data.objects["Cube"].location += prod_vec

They spawn 10 threads, each access the same data in, allegedly, concurrent fashion. This kind of stuff is what I mean by “thread-safety” and this is where concern should arise. Interestingly, they say it is okay (???).

But then down below:

So far, no work has been done to make Blender’s Python integration thread safe, so until it’s properly supported, it’s best not make use of this.

The explanation there is indeed a bit confusing. What it boils down to is:

  • Python threads accessing data through the bpy API concurrently with Blender threads is not supported.
  • Multiple Python threads accessing data through the bpy API works. But that’s only because there is no actual concurrency here, as Python doesn’t do actually execute anything concurrently. So it’s rather useless that this works.

What do you mean? There is concurrent.futures and ThreadpoolExecutor. It is not explicitly parallel per se, but due to asynchronyous nature it can shutdown context1 on whatever thread while it is accessing bpy API data and then resume context2 on any other thread from threadpool that modifies aforementioned data. Now, when context1 is resumed the data it acquired access to before is in inconsistent state.