Threading problems

import threading
import time
from direct.directbase import DirectStart
from direct.task import Task


class ThreadExample(threading.Thread):
    def __init__(self, tName):
        threading.Thread.__init__(self)
        self.tName = tName
    def run(self):
        while True:
            print '[%s] Time: %s'%(self.tName, time.time())


def pandaWork(task, args=None):
    print '[Panda] Time: %s'%time.time()
    return Task.cont

thr1 = ThreadExample('Thread1')
thr2 = ThreadExample('Thread2')

taskMgr.add(pandaWork, 'pandawork')
thr1.start()
thr2.start()
run()

Hi.
I can`t solve problem whit this example. Where is the problem ?!
1.Test
Kubuntu Karmic. Python 2.6.4, Panda3D 1.6.2(simple threads)
Results:
~50 messages from Thread1 for about 20ms.
~50 messages from Thread2 for about 20ms.
~150 messages from Panda for about 14 seconds.(and no messages from Thread1 or 2)
2.Test
Ubuntu Jaunty. Python 2.6.2, Panda3D 1.6.2(simple threads)
Results:
~50 messages from Thread1 for about 20ms.
~50 messages from Thread2 for about 20ms.
~150 messages from Panda for about 4 seconds.(and no messages from Thread1 or 2)
3.Test
Windows 2003. Python 2.5.2, Panda3D 1.6.2(simple threads)
~20 messages from Thread1 for about 10ms.
~20 messages from Thread2 for about 10ms.
~1 message from Panda.(next message is immediately and from Thread1)

So. My question … Where is the problem, and why results are so different. Panda not works good with newer version of Python? I recompile panda on Karmic, but I don`t see big difference from first test.

The first question is, what behavior do you expect to see?

Remember that Python does not support threading in the normal sense, because it uses a Global Interpreter Lock (GIL) to ensure that only one thread runs at a time. This is necessary because the Python interpreter itself isn’t thread-safe. In Python, you can use threads to help you implement co-routine based algorithms, but you shouldn’t expect any performance gains from parallelism.

That being said, the performance envelope of when “threads” switch context probably varies greatly from one OS to another. That’s why you’re seeing different numbers in your above test. But it really doesn’t matter what numbers you see, because you shouldn’t expect Python threads to perform the way you expect C threads to.

David

I dont expect to see perfectly arranged messages form Thread1, Thread2 and Panda. But .. "holding" pandas thread for 14 seconds … ? If this is normal i will change my app to use panda and panda`s Threads.

The Python GIL works by switching contexts after every n Python instructions. Since your Panda thread isn’t executing very many Python instructions, it might be a while before it switches, so yes, this is more-or-less expected behavior.

However, depending on your precise needs, you should probably be using Panda threads anyway, since there is a very severe danger of corrupting your memory image if you mix-and-match Python threads and Panda code.

You can switch to using Panda threads easily, by importing direct.stdpy.threading instead, and by calling PandaModules.Thread.considerYield() within all of your thread loops.

Note, though, that Panda threads may give you similar problems, at least as they are compiled by default, because Panda also doesn’t use true threads by default: it uses what it calls “simple threads”, which really means cooperative context-switching within the same process. Again, you won’t get parallelism.

If you really want parallelism, you will have to compile Panda yourself to use true threads, and then don’t use Python (or limit your use of Python).

If all you want is to have tasks that run as co-routines, consider using Panda’s tasks instead of using threads.

David

Thanks a lot for information, David :slight_smile: