Multithreading Python SOP Crash

   4833   4   2
User Avatar
Member
58 posts
Joined: July 2013
Offline
I am working on writing a multi threaded Python SOP using the ‘threading’ Python module. When I call any hou module functions from within the threaded function and later try to join all of the threads, Houdini will freeze.

When executed, the following code will produce this output:

import threading

def runThread():
print hou.time()

threads =

print “Begin”

for i in range(3):
t = threading.Thread(target=runThread)
threads.append(t)
t.start()

print “End”


>>> Begin
End
0.0
0.0
0.0


Without calling the join() function, I am able to use any command in the hou module and have Houdini continue to run correctly. Sometimes threads will take longer than others, so changing attributes might pop in once the threads are done cooking.
However, I want to be able to have the Python SOP wait for all of the threads to finish, before it finished its cooking operation.

I want an output like this:
>>> Begin
0.0
0.0
0.0
End


However, if I call join() it will die if and only if any hou command was called.
For example, the following code dies.

import threading

def runThread():
print hou.time()

threads =

print “Begin”

for i in range(3):
t = threading.Thread(target=runThread)
threads.append(t)
t.start()

for t in threads:
t.join()
print “End”

But the following does this:

import threading

def runThread(i):
print i

threads =

print “Begin”

for i in range(3):
t = threading.Thread(target=runThread, argsi,))
threads.append(t)
t.start()

print “End”
>>> Begin
0
1
2
End

This is telling me something in the hou module is dying or reaching an infinite loop when hou commands are called in parallel. Any help would be much appreciated. Thanks
User Avatar
Member
7025 posts
Joined: July 2005
Offline
I'll be very (but pleasantly) surprised if Houdini can execute threaded Python.
User Avatar
Member
1906 posts
Joined: Nov. 2006
Offline
I suspect the issue has to do with thread lock contention. Most (if not all) HOM functions always acquire the GIL and I suspect the join() calls are causing some badness when the threaded functions are trying to run HOM. Houdini can definitely run general threaded Python code but Houdini's Python functions aren't really designed for threading. Combine that with the fact you're trying to do it from within a cooking node and that sounds like automatic sadness to me.

What's the end goal of this? Multithreaded geometry modification given that you're using a SOP, I'd imagine?
Graham Thompson, Technical Artist @ Rockstar Games
User Avatar
Member
58 posts
Joined: July 2013
Offline
graham
What's the end goal of this? Multithreaded geometry modification given that you're using a SOP, I'd imagine?

Precisely. I'm wondering if there is an efficient way to get the geometry data into Python data structures that are thread safe.
Maybe then just save all of the HOM calls using an array of strings and running them with Python exec function?
User Avatar
Member
1906 posts
Joined: Nov. 2006
Offline
Your best bet for efficient geometry data access and modification is to use the hou.Geometry.FloatAttirbValues() and corresponding setters. You could potentially use these lists of data in different threads and then set them back in the main one since they are very fast.

Depending on what you are actually trying to accomplish and what your geometry size is, you might be better to just attempt this in HDK/inlinecpp. Python geometry manipulation is great but it definitely has scaleability issues.

To me, if you're worried about trying to multithread things then I think it's not a job for HOM.
Graham Thompson, Technical Artist @ Rockstar Games
  • Quick Links