WorldViz User Forum

WorldViz User Forum (https://forum.worldviz.com/index.php)
-   Vizard (https://forum.worldviz.com/forumdisplay.php?f=17)
-   -   Multithreading in Vizard 3.0 (https://forum.worldviz.com/showthread.php?t=1355)

RedSpikeyThing 02-19-2008 01:22 PM

Multithreading in Vizard 3.0
 
I'm currently using Vizard 3.0 and having trouble getting a simple multithreaded application to run. I wrote a script in IDLE using Python 2.3 (the same version as Vizard) and it works as expected. When it is run in Vizard, however, I get the following error:

"Unhandled exception in thread started by
Error in sys.excepthook:
Original exception was:
Unhandled exception in thread started by
Error in sys.excepthook:
Original exception was:
Unhandled exception in thread started by
Error in sys.excepthook:
Original exception was:
Unhandled exception in thread started by
Error in sys.excepthook:
Original exception was:"

The code is pretty simple and, as I said before, works as expected in IDLE.

Code:

import thread

def countingThread(id, maxVal):
    global printLock
    for i in range(maxVal):
        printLock.acquire()
        print "Thread ", id, ": ", i
        printLock.release()

global printLock
printLock = thread.allocate_lock()
for i in range(5):
    thread.start_new_thread(countingThread, (i, 50))

Any help would be greatly appreciated!!

farshizzo 02-19-2008 02:10 PM

The problem is that your script does not wait for the threads to complete before exiting. I've modified your script to use the more advanced threading module. It will also wait for all the threads to complete before exiting. Here is the code:
Code:

import threading

#Create mutex for printing
printLock = threading.Lock()

def countingThread(id, maxVal):
        global printLock
        for i in range(maxVal):
                printLock.acquire()
                print "Thread ", id, ": ", i
                printLock.release()

threads = []
for i in range(5):
        #Create and start the threads
        t = threading.Thread(target=countingThread, args=(i, 50))
        t.start()
       
        #Save thread object to list
        threads.append(t)

#Wait for threads to complete
for t in threads:
        t.join()


RedSpikeyThing 02-19-2008 02:24 PM

Great, thank you! Is there any reason this works correctly in IDLE but not in Vizard?

farshizzo 02-19-2008 02:28 PM

Technically, your code should not work. I think the reason it works with IDLE is that IDLE runs the script in its embedded interpreter, which does not exit until the GUI is closed. If you ran the script directly from the command line, my guess would be that it would have the same problem as Vizard.

RedSpikeyThing 02-20-2008 11:32 AM

That makes sense. I have one more question:

I would like to run a thread that monitors a bunch of sensors for a particular pattern. I set up a deamon thread that runs in a "while true:" loop, but this is still causing some problems.

I also considered setting this up as an event, but I don't see how I can build a custom event that requires parameters being passed to the constructor.

This is getting very frustrating because what I want to do is conceptually simple, but seems to be difficult to implement. Any advice would be appreciated.

farshizzo 02-20-2008 11:38 AM

What is the problem with your "while True:" loop? Are you yielding to other threads in the loop by issuing a time.sleep(...) call?

Are you talking about a custom threading event or a Vizard event?

RedSpikeyThing 02-20-2008 12:30 PM

Quote:

Originally Posted by farshizzo (Post 5082)
What is the problem with your "while True:" loop? Are you yielding to other threads in the loop by issuing a time.sleep(...) call?

Are you talking about a custom threading event or a Vizard event?

The code I am using is supposed to spew out number until the program stops:
Code:

import viz
import threading

class ThreadedClass (threading.Thread):
        def run(self):
                i = 0
                while True:
                        i = i + 1
                        print i

t = ThreadedClass()
t.setDaemon(True)
t.start()

viz.go()

This code should just print successive numbers until the program is terminated. The output I get, however, is as follows:

1
2

1051
** Load Time: 0.12 seconds
1052
1053

1066

No matter how long the program is run for, it terminates at 1066. Also, the numbers 1052 to 1056 do not appear in the output window until the main program is stopped. It appears as if the thread is not running past a certain number of iterations.

I've been looking around for resources on how to do this, but I am having difficulty finding any. Do you have any references so that I don't have to post for every problem I encounter?

As always, thanks I appreciate the help.

farshizzo 02-20-2008 12:42 PM

Try adding the following line to your script:
Code:

viz.directormode(viz.DIRECTOR_FAST)
This tells Vizard to allow Python threads to run while Vizard is drawing. Technically speaking, this will instruct Vizard to relase the GIL while rendering. For more information about the GIL and how Python threads behave, have a look at this page, http://docs.python.org/api/threads.html

RedSpikeyThing 02-20-2008 12:48 PM

Wow you're quick on the draw. That worked perfectly! Thanks for the help and the reference....hopefully I won't have to bug you anymore ;)

Gladsomebeast 10-17-2008 05:05 PM

Is using threading.Threads objects possible while running a Vizard sim without the viz.directormode call? In other words, must you set the director mode when you want to run threading.Threads while running a Vizard sim?

farshizzo 10-17-2008 05:16 PM

It depends. The call to viz.directormode(viz.DIRECTOR_FAST) simply tells Vizard to allow other Python threads to run while it is rendering. If you don't have this flag set, then the only time your Python thread will run is after 100 Python virtual instructions have been executed in the main thread (see sys.setcheckinterval in the Python docs for more info).

If your thread is only performing computations or file i/o, then I would recommend setting this flag. If your thread is modifying the Vizard scene graph, then I would NOT set this flag.


All times are GMT -7. The time now is 12:20 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Copyright 2002-2023 WorldViz LLC