Python Thread Problem

Im trying to use a another thread in python but as soon as another python script get called Blender 2.49b just stop running the thread… why? dunno…

How can I get around this bug?

To reproduce it:

  1. Start the following script and monitor the console:


import thread
from thread import *

def thread_callback(num, *args):
	
	while( 1 ):
		num = num + 1
		print num
		

test = 0
thread.start_new_thread( thread_callback, (test,1) )

  1. Start another script ie in the 3D viewport

Space Bar -> Add -> Mesh -> Torus

As soon as the Torus script GUI appear the thread will just stop… and its impossible to restart it even if the script is executed again… Any “known” work around?

I am successfully using threading module with and without the blender gui.
give this a shot.
import threading
class ThreadRunner(threading)
def init(self):
self.thread.init(target=self.target,args=[])
self.start()
self.needed=1
self.inc=0
self.queue=[]
def target(self):
while(self.needed):
time.sleep(1)
self.inc+=1
aCmd=self.queue.pop()
if (aCmd):
exec(aCmd)

Doesn’t seems to work for me… Still have the same problem… Maybe I got the formatting of the code above wrong? And is this for Blender v2.49?

In addition, have you try to run this piece of code against the bug steps that I give above? Did it work for you?

TIA

Cheers,

Just had a shot at it using threading and its the same result…


import Blender
import threading
import time

class thread_test( threading.Thread ):
	
	def __init__(self):
		
		threading.Thread.__init__(self)

	def run(self):
		
		while( 1 ):
			print time.time()	
			time.sleep(1)			

def register_ui():
	
	Blender.Draw.Register( draw_ui, None, event_ui )
	
def draw_ui():
	
	dummy = 0

def event_ui( event ):

	print event


if __name__ == '__main__':
	register_ui()
	
	t = thread_test()
	t.setDaemon(True)
	t.start()

Once again to reproduce the bug that cause the thread to just start hanging somewhere try the following:

  1. Run the script

  2. Start ANY other python script from within Blender v2.49

Ex:

3D View -> Space Bar -> Add -> Mesh -> EmptyMesh

The thread will just stop printing the time and will never come back to life until you .join() it back to the main thread… If you query with enumerate() you will see that the thread is there, started and alive… Its just hanging, frozen somewhere… Very weird…


import threading

for t in threading.enumerate():
	print t
	print t.isAlive()
	print

I really hope that someone can help me on this Im stuck and currently can’t go forward until this is fixed…

TIA

If found a quick fix but its dirty… REALLY dirty… and doesn’t really “wake up” the thread… just push it to be executed frame by frame…

Using scriptlink on redraw:


import Blender
import time

Blender.Draw.Redraw(1)
time.sleep( 1.0 / 60.0 )

I would really like to hear a real solution to the problem…

I think the blender program is flushing stdout, hence why you dont see anything "print"ed from python, use sys.stderr
I remember its the only reliable way of printing out of a python script. Also if your starting the program with -P <script> there is a lot of problem’s I have encountered.

Actually this is a problem with the console that is written in the blender processing fashion, running threads works fine if you start them with blender, This does have some drawbacks , example:

import sys,threading,time
#import curses,tempfile
#python2.6
import builtin
#python3.1
#import builtins

class _thread(threading.Thread):
import sys,time,bpy,Blender
def load_gui(self):
self.gui_load=1
def exit(self):
self.pout(“Killing Session”)
self._Thread__stop()
self.notdone=0
self.gui_load=1
def quit(self):
self.pout(“Killing Session”)
self._Thread__stop()
self.notdone=0
self.gui_load=1
class WrapExceptions():
def init(self,msg,type=None):
if (type==None):
self.type=‘WrapExceptions’
else:
self.type=type
self.msg=’ ‘.join([":’’’",self.type,msg,"’’’"])
def str(self):
return(“Exception: “+self.msg.str())
def repr(self):
return(self.msg)
def pout(self,arg):
self.stdout.write(arg.str())
def pin(self):
return(self.stdin.readline())
def _init(self):
self.notdone=1
self.gui_load=0
self.stdin=sys.stdin
self.stdout=sys.stderr
#self.scr=curses.initscr()
#self.inwin=curses.newwin()
#self.sbuf=[tempfile.TemporaryFile(),tempfile.TemporaryFile()]
#self.scr.putwin(self.sbuf[0])
#self.sbuf[0].seek(0)
#curses.savetty()
self.init(target=self._slave_thread,args=[])
self.start()
def build_globals(self,objects):
ret={‘all’:[]}
for anObj in objects:
dl=self.builtins.dir(anObj)
ret[‘all’].append(dl)
for Objs in dl:
ret[Objs.str()]=anObj.getattribute(Objs.str())
return(ret)
def _slave_thread(self):
cmdStr=’’;ind=0;cmdHistory=[];cmdP=0;indent=’ ‘;
self.LastExc=self.WrapExceptions(self.str())
self.local=self.build_globals([self.builtins,self])
self.pout(’#For import; use setattr(builtins,‘name’,import(‘name’))
‘)
try:
while(self.notdone):
if (cmdStr==’’):
self.pout(’
>>> ‘)
else:
self.pout(’
… ‘+indent)
cmdStr+=self.pin()
#cmdStr+=curses.getch()
p=cmdStr.len()
while (p>0):
if (cmdStr[p-1]==’:’):
indent+=’ ’
break
elif(cmdStr[p-1].eq(” “) or cmdStr[p-1].eq(”
“)):
p-=1
#elif(cmdStr[p-1].eq(”\x1b”)):
# cmdHistory.insert(cmdP,cmdStr)
# if (cmdHistory.len()>cmdP):
# pout("
“+cmdHistory[cmdP])
# else:
# pout(”
")
else:
try:
#code=self.builtins.compile(cmdStr,’’,‘exec’)
#self.builtins.eval(code,self.local)
exec(cmdStr,self.local)
except:
print(self.LastExc.str())
cmdStr=’’
break
except(self.WrapException):
print "Exception Raised Above Main.
"
#finally:

curses.endwin()

curses.resetty()

def m_Gc(target):
while(target.notdone and not target.gui_load):
time.sleep(1)
if (not target.isAlive()):
target._init()

thread=_thread()
thread.builtins=builtin
thread._init()
m_Gc(thread)

I think the blender program is flushing stdout, hence why you dont see anything "print"ed from python, use sys.stderr

No dude, I can guarantee you at 100% certainty that the thread is not running, it is simply frozen and hanging somewhere… Try my test up there, simply remember the last number printed, mess around with other scripts to force to get another output and you’ll see… The thing is I test that with a TCP connection, and when this happen the server doesn’t receive anything, hence my conclusion that it is frozen.