[PyKDE] Broken QThread Support Under Windows
Phil Thompson
phil at river-bank.demon.co.uk
Sun Dec 8 19:03:01 GMT 2002
Paul,
Thanks for this - it was very helpful.
I had tried Qt 3.1.0 but it didn't seem to have improved things.
I then changed the implementation of QSemaphore.__iadd__() and __isub__ so
that they used ++ (and --) instead of += (and -=) when the value was one. The
semaphore.py script now works with Qt 3.0.5. I haven't yet tested against Qt
3.1.0, but I feel confident it will work.
Phil
On Saturday 07 December 2002 9:31 pm, Paul Felix wrote:
> > Qt v3.0.5 and later versions have broken threading in PyQt under Windows
> > - Linux/Unix are fine. You can see the effect running the semaphore.py
> > example.
> >
> > I had a brief email exchange with somebody when this was first noticed
> > some months ago, who suggested what the change in Qt might have been to
> > cause the problem.
> >
> > I'm now trying to get to the bottom of this - but I don't seem to have a
> > record of the email exchange.
> >
> > Does this ring a bell with anybody - was it you?
> >
> > Thanks,
> > Phil
>
> Hi Phil,
>
> That was me. I was able to reproduce the problem using the C++ example.
> I'm using Windows 2000 and MSVC 6.0 SP5.
>
> To get the C++ example to lock up, try the following:
>
> * Change all semapahore access increment occurances from "++" to "+= 1"
> * Change all semapahore access decrement occurances from "--" to "-= 1"
>
> Obviously, you had to make that change in the PyQt example, as the "++" and
> "--" operator methods are not available.
>
> I sent a report to Trolltech, and Volker Hilsheimer tried to reproduce it,
> but couldn't. He sent me his diffs of the semaphore example code, and it
> looked like he made the proper changes -- so we were stumped and I dropped
> it. I'm curious to see if you can reproduce it.
>
> Actually, now that you have resurrected this issue, I think I have found
> the problem. It's an elusive one that involves a thread race condition, so
> that may explain why Volker couldn't reproduce it...
>
> When a thread makes a call to acquire a semaphore's accesses, the call
> blocks until the requested access count is available. When another thread
> releases accesses to a semaphore, the semaphore must do the following:
>
> 1. Decrement the access count
> 2. Release the waiting thread(s).
>
> That order is quite important. In the case of the operator+=() method, as
> soon as it's thread is released, it's going to check the access count to
> see if there are enough accesses available. If there aren't enough
> accesses available, it will go back into wait mode.
>
> However, if you look at QSemaphore::operator-=() in qsemaphore_win.cpp, you
> will see that the waiting threads are released BEFORE the access count is
> decremented. If you fix that order, the semaphores example (using "+=1"
> and "-=1) will work.
>
> Why did it stop working in Qt 3.0.5? It's all a little convoluted, but the
> short answer has to do with a change in QWaitCondition:wakeAll() (in
> qwaitcondition_win.cpp), where a call to Windows SetEvent() was changed to
> PulseEvent().
>
> Hmmm, I just looked at Qt 3.1.0, and they changed it back to calling
> SetEvent()! So, the PyQt example may work with Qt 3.1.0! I wonder why
> they changed it back?
>
> IMHO, the code in qsemaphore_win.cpp looks a bit questionable in places.
> The code in qsemaphore_unix.cpp looks platform-independent to me -- it uses
> QMutex and QWaitCondition only. I don't know why it couldn't be used on
> Windows too. It should work, right?
>
> Paul
More information about the PyQt
mailing list