[Pythonmac-SIG] Threading and FrameWork.Application

Jack Jansen Jack.Jansen@oratrix.com
Sun, 7 Apr 2002 23:21:07 +0200


On zaterdag, april 6, 2002, at 11:15 , Alexandre Parenteau wrote:

>> Jack Jansen wrote:
>>
>>> Does anyone have any suggestions as to what mainloop() could do
>>> to give time to other threads? There must be a way to do this,
>>> but I don't immediately see it...
>>
>> Erm, aren't we talking about pre-emptive threads here? If I 
>> recall correctly
>> GUSI only switches contexts when I/O blocks, so it doesn't 
>> really implement
>> pre-emptive threads. Yet I think GUSI is to blame for that, 
>> not FrameWork's
>> mainloop. As in: it should work correctly in MachoPython. Am I missing
>> something?
>
> GUSI yield to other cooperative threads, not only when I/O 
> blocks (it's in
> GUSIContext::Yield(). But the YieldToAnyThread that GUSI is 
> doing is likely
> to do nothing on Python threads because typically these Python 
> threads are
> locked and wait for the current Python thread to give away the lock.

Well, the call I'm looking for would definitely have to give up 
the global interpreter lock before doing the call to give up the 
CPU. And it turns out GUSI's sleep(0) (or usleep(0), for that 
matter) does exactly what we want: it allows a threadswitch 
without further delay.

But unfortunately Python's time.sleep() doesn't call sleep or 
usleep: it calls select(0, NULL, NULL, NULL, 0). And select with 
no filedescriptors doesn't do anything. And even with 
filedescriptors but zero timeout it never switches threads.

So, the fix is going to have to be partially in C: time.sleep(0) 
should call sleep(0), not select. And it's too late for 2.2.1, 
so this will have to wait for 2.2.2 and 2.3.

In the mean time, Pieter, for your specific case you can add the 
following code to your Application class (it's not a good idea 
in general, because it slows down the main loop, but in Pieter's 
case the main loop isn't supposed to do anything anyway except 
wait for quit).

        def getevent(self, mask = everyEvent, wait = None):
            time.sleep(0.1)
            return Framework.Application.getevent(self, mask, wait)
--
- Jack Jansen        <Jack.Jansen@oratrix.com>        
http://www.cwi.nl/~jack -
- If I can't dance I don't want to be part of your revolution -- 
Emma Goldman -