473,394 Members | 1,752 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Using PyOpenGL what should I use for a GUI ?

Hi I have started a small project with PyOpenGL. I am wondering what
are the options for a GUI. So far I checked PyUI but it has some
problems with 3d rendering outside the Windows platform.

I know of WxPython but I don't know if I can create a WxPython window,
use gl rendering code in it and then put widgets on top of that...

Jul 18 '05 #1
4 2862
I am using Python 2.2.2 on RH9, and just starting to work with Python
threads.

I started using the threading module and found that 10-20% of the runs
of my test program would hang. I developed smaller and smaller test
cases, finally arriving at the program at the end of this message,
which uses the thread module, not threading. This program seems to
point to problems in Python thread scheduling.

The program is invoked like this:

python threadtest.py THREADS COUNT

THREADS is the number of threads created. Each thread contains a loop
that runs COUNT times, and all threads increment a counter. (The
counter is incremented without locking -- I expect to see a final
count of less than THREADS * COUNT.)

Running with THREADS = 2 and COUNT = 100000, most of the time, the
program runs to completion. About 20% of the time however, I see one
thread finish, but the other thread never resumes.

Here is output from a run that completes normally:

[jao@black]$ python threadtest.py 2 100000
nThreads: 2
nCycles: 100000
thread 1: started
thread 1: i = 0, counter = 1
thread 2: started
thread 2: i = 0, counter = 2691
thread 1: i = 10000, counter = 13496
thread 2: i = 10000, counter = 22526
thread 1: i = 20000, counter = 27120
thread 2: i = 20000, counter = 40365
thread 1: i = 30000, counter = 41264
thread 1: i = 40000, counter = 55922
thread 2: i = 30000, counter = 58416
thread 2: i = 40000, counter = 72647
thread 1: i = 50000, counter = 74602
thread 1: i = 60000, counter = 88468
thread 2: i = 50000, counter = 99319
thread 1: i = 70000, counter = 110144
thread 2: i = 60000, counter = 110564
thread 2: i = 70000, counter = 125306
thread 1: i = 80000, counter = 129252
Still waiting, done = 0
thread 2: i = 80000, counter = 141375
thread 1: i = 90000, counter = 147459
thread 2: i = 90000, counter = 155268
thread 1: leaving
thread 2: leaving
Still waiting, done = 2
All threads have finished, counter = 168322

Here is output from a run that hangs. I killed the process using
ctrl-c.

[jao@black]$ python threadtest.py 2 100000
nThreads: 2
nCycles: 100000
thread 1: started
thread 1: i = 0, counter = 1
thread 2: started
thread 2: i = 0, counter = 990
thread 1: i = 10000, counter = 11812
thread 2: i = 10000, counter = 13580
thread 1: i = 20000, counter = 19127
thread 2: i = 20000, counter = 25395
thread 1: i = 30000, counter = 31457
thread 1: i = 40000, counter = 44033
thread 2: i = 30000, counter = 48563
thread 1: i = 50000, counter = 55131
thread 1: i = 60000, counter = 65291
thread 1: i = 70000, counter = 78145
thread 2: i = 40000, counter = 82715
thread 1: i = 80000, counter = 92073
thread 2: i = 50000, counter = 101784
thread 1: i = 90000, counter = 104294
thread 2: i = 60000, counter = 112866
Still waiting, done = 0
thread 1: leaving
Still waiting, done = 1
Still waiting, done = 1
Still waiting, done = 1
Still waiting, done = 1
Still waiting, done = 1
Still waiting, done = 1
Still waiting, done = 1
Still waiting, done = 1
Traceback (most recent call last):
File "threadtest.py", line 26, in ?
time.sleep(1)
KeyboardInterrupt
[jao@black osh]$

In this case, thread 1 finishes but thread 2 never runs again. Is
this a known problem? Any ideas for workarounds? Are threads widely
used in Python?

Jack Orenstein

# threadtest.py

import sys
import thread
import time

nThreads = int(sys.argv[1])
nCycles = int(sys.argv[2])
print 'nThreads: %d' % nThreads
print 'nCycles: %d' % nCycles
counter = 0
done = 0

def run(id):
global done
print 'thread %d: started' % id
global counter
for i in range(nCycles):
counter += 1
if i % 10000 == 0:
print 'thread %d: i = %d, counter = %d' % (id, i, counter)
print 'thread %d: leaving' % id
done += 1

for i in range(nThreads):
thread.start_new_thread(run, (i + 1,))
while done < nThreads:
time.sleep(1)
print 'Still waiting, done = %d' % done
print 'All threads have finished, counter = %d' % counter
Jul 18 '05 #2
This may help.
http://linuxgazette.net/107/pai.html
Also be sure to google.
search strategy:
Python threading
Python threads
Python thread tutorial
threading.py example
Python threading example
Python thread safety
hth,
M.E.Farmer

Jul 18 '05 #3
Jack Orenstein wrote:
I am using Python 2.2.2 on RH9, and just starting to work with Python
threads.
Is this also the first time you've worked with threads in general,
or do you have much experience with them in other situations?
This program seems to point to problems in Python thread scheduling.
While from time to time bugs in Python are found, it's generally
more productive to suspect one's own code. In any case, you
wouldn't have posted it here if you didn't suspect your own
code at least a bit, so kudos to you for that. :-)
done = 0
def run(id):
global done
print 'thread %d: started' % id
global counter
for i in range(nCycles):
counter += 1
if i % 10000 == 0:
print 'thread %d: i = %d, counter = %d' % (id, i, counter)
print 'thread %d: leaving' % id
done += 1

for i in range(nThreads):
thread.start_new_thread(run, (i + 1,))
while done < nThreads:
time.sleep(1)
print 'Still waiting, done = %d' % done
print 'All threads have finished, counter = %d' % counter


Without having tried to run your code, and without having studied
it for long, I am going to point out something that is at the
very least an inherent defect in your code, though you might
not have used Python (or threads?) for long enough to realize
why. Note that I don't know if this is the cause of your
particular problem, just that it _is_ a bug.

You've got two shared global variables, "done" and "counter".
Each of these is modified in a manner that is not thread-safe.
I don't know if "counter" is causing trouble, but it seems
likely that "done" is.

Basically, the statement "done += 1" is equivalent to the
statement "done = done + 1" which, in Python or most other
languages is not thread-safe. The "done + 1" part is
evaluated separately from the assignment, so it's possible
that two threads will be executing the "done + 1" part
at the same time and that the following assignment of
one thread will be overwritten immediately by the assignment
in the next thread, but with a value that is now one less
than what you really wanted.

Look at the bytecode produced by the statement "done += 1":
import dis
def f(): .... global done
.... done += 1
.... dis.dis(f)

3 0 LOAD_GLOBAL 0 (done)
3 LOAD_CONST 1 (1)
6 INPLACE_ADD
7 STORE_GLOBAL 0 (done)
(ignore the last two lines: they just "return None")
10 LOAD_CONST 0 (None)
13 RETURN_VALUE

Note here the "store_global" that is separate from the add
operation itself. If thread A gets loses the CPU (so to speak)
just before that operation, and thread B executes the entire
suite of operations, then later on when thread A executes
that operation it will effectively result in only a single
addition operation being performed, not two of them.

If you really want to increment globals from the thread, you
should look into locks. Using the "threading" module (as is
generally recommended, instead of using "thread"), you would
use threading.Lock(). There are other thread synchronization
primitives in the threading module as well, some of which
might be more suitable for your purposes. Note also the
oft-repeated (in this forum) recommendation that if you simply
use nothing but the Queue module for inter-thread communication,
you will be very unlikely to stumble over such issues.

-Peter
Jul 18 '05 #4
Peter Hansen wrote:
Jack Orenstein wrote:
I am using Python 2.2.2 on RH9, and just starting to work with Python
threads.

Is this also the first time you've worked with threads in general,
or do you have much experience with them in other situations?


Yes, I've used threading in Java.
You've got two shared global variables, "done" and "counter".
Each of these is modified in a manner that is not thread-safe.
I don't know if "counter" is causing trouble, but it seems
likely that "done" is.
I understand that. As I said in my posting, "The counter is
incremented without locking -- I expect to see a final count of less
than THREADS * COUNT." This is a test case, and I threw out more and
more code, including synchronization around counter and done, until it
got as simple as possible and still showed the problem.
Basically, the statement "done += 1" is equivalent to the
statement "done = done + 1" which, in Python or most other
languages is not thread-safe. The "done + 1" part is
evaluated separately from the assignment, so it's possible
that two threads will be executing the "done + 1" part
at the same time and that the following assignment of
one thread will be overwritten immediately by the assignment
in the next thread, but with a value that is now one less
than what you really wanted.
Understood. I was counting on this being unlikely for my test
case. I realize this isn't something to rely on in real software.

If you really want to increment globals from the thread, you
should look into locks. Using the "threading" module (as is
generally recommended, instead of using "thread"), you would
use threading.Lock().


As my note said, I did start with the threading module. And variables
updated by different threads were protected by threading.Condition
variables. As I analyzed my test cases, and threading.py, I started
suspecting thread scheduling. I then wrote the test case in my email,
which does not rely on the threading module at all. The point of the
test is not to maintain counter -- it's to show that sometimes even
after one thread completes, the other thread never is scheduled
again. This seems wrong. Try running the code, and let me see if you
see this behavior.

If you'd like, replace this:

counter += 1

by this:

time.sleep(0.000001 * id)

You should see the same problem. So that removes counter from the
picture. And the two increments of done (one by each thread) are still
almost certainly not going to coincide and cause a problem. Also, if
you look at the output from the code on a hang, you will see that
'thread X: leaving' only prints once. This has nothing to do with what
happens with the done variable.

Jack
Jul 18 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Jimmy Johns | last post by:
Hi, why hasn't there a version of pyOpenGL for python 2.3.x yet? Currently the binary installers for windows only work with python 2.2, and will give an when installing for python 2.3. I can't...
3
by: Steven Gutstein | last post by:
This is probably a fairly newbie type problem, but I'm trying to use PyOpenGL, and don't seem to have installed it correctly. I'm running Python 2.3 on a Windows NT machine. Whenever I go into...
1
by: Kirill Kuvaldin | last post by:
Hello All! My program in python uses PyOpenGL and I need to convert it to a standalone windows executable file. Following to these instructions...
29
by: 63q2o4i02 | last post by:
Hi, I'm interested in using python to start writing a CAD program for electrical design. I just got done reading Steven Rubin's book, I've used "real" EDA tools, and I have an MSEE, so I know what...
5
by: Sébastien Ramage | last post by:
Bonjour à tous, Dans la folie j'ai installé le nouveau python, impatient de voir les nouveautés mais je pense que j'ai été un peu rapide car j'ai voulu utiliser pyOpenGL et là problème il...
1
by: joroy | last post by:
Hi all, I think this is ctypes related but how can I call the glShaderSourceARB function? The function have this header: glShaderSourceARB( GLhandleARB(shaderObj), GLsizei(count),...
0
by: sweetmelon | last post by:
(I'm a newbie in Python and pyOpenGL.) Environment: WinXP SP2 Python ver. 2.5 WingIDE easy_install is installed PIL, pyNum is installed Download PyOpenGL-3.0.0a5-py2.5.egg run: easy_install...
5
by: Extremist | last post by:
I am currently sitting with a problem concering pyOpenGL. PyOpenGL is the combination of OpenGL and Python. Is there a new version of PyOpenGL to go with wxPython 2.6 other than that of which is...
2
by: seb.haase | last post by:
Hi, I am distributing a package with a precompiled collection of modules and packages useful for Python based medical/biological/astronomical image analysis and algorithm development. (Codename:...
0
by: Colin J. Williams | last post by:
I have just installed PyOpenGL and get a series of warning messages: Best match: PyOpenGL 3.0.0b3 Downloading...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.