It has come to my attention that various people are having difficulties achieving multi threading in the bge. I have successfully done this on two occasions, using two different techniques. The first involves using pyOpenCl to preform procedural hightmap creation on the video card. The second involves using popen on blenders python executable to run a nonblocking networking server/client. In neither case is the sub process able to directly access the bge module. It’s possible that something might be done using ctypes and memory pointers, or maybe using numpy arrays from bytes, but this is currently beyond me, so if it can be done I don’t know how.
pyOpenCl
PyOpenCl can be difficult to install. Difficult enough that it may not be realistic on a consumers computer. If you can get it to install it can be extremely powerful. One of the things video cards are designed for is texture handling, which is basically what I was doing. I got about a 200x performance increase. Thats approximately three minutes down to one second.
Note that pyOpenCl uses pythons internal garbage collection. Things will be taken off the video card at the same time there removed from python. Also pyOpenCl would not compete for memory. If blender used all the video ram, pyOpenCl would simply fold and raise oom. Make sure you put everything in memory as soon as possible and keep it there. Also, insure you only compile your kernel once.
popen
If you know the location of blenders internal python executable, then you can run a python script with it using popen. Unfortunately blenders sys module returns the wrong values. I believe @wkk has a better way of finding it then I do. His method is in his BgeZ module.
If you use the internal player, the process will run until blender is closed. If you use the external player, then it will close when the external player closes. So run your game by clicking “Run in External Player”, rather then hitting “p”. Inorder to read exceptions in the second process, you can use an exception logger with exception hook.
I haven’t been able to get popens standard out to work, so I communicated with the second process using socket. I though “Udp should be reliable enough on local host.”, but I was having connection problems when the processor was overloaded. So now I think “Tcp should be fast enough on local host.”, but ya, I was wrong once. If anyone can figure out a better way to get the data out, please let me know.
cmd = [pathExe, pathPy] + args
pid = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)