DoEvents equiv?

Carlos Ribeiro cribeiro at mail.inet.com.br
Thu May 10 21:46:56 EDT 2001


Mark,

I think that I don't have made myself clear... it's my fault, so let's try 
to clarify the issues. Again the disclaimer: I'm not an expert on the issue 
but I think I did my homework. Please correct me if I'm wrong. I apologize 
for any mistake.

Windows uses a mixed cooperative-preemptive scheduler. In earlier versions, 
the cooperative portion was bigger. In fact, it was relatively easy to lock 
up the computer with a misbehaved program. You needed to explicitly yield 
CPU time to the other processes. There was a API call (called Yield :-) 
just for that.

Since Win31, and specially since Windows 95, we have seen the preemptive 
part of Windows growing bigger. Now the OS does have something closer to a 
scheduler. Each process has it's own message queue, and Windows does some 
work to keep everything running without any process starving. If a single 
process stops checking the message queue, the process is dead though. When 
it happens you need to Ctrl-Alt-Del|Finalize to kill the process.

Now what's the problem here? *In my experience*, PythonWin is particularly 
irresponsive sometimes. If I spray PumpWaitingMessages around my scripts, 
everything run fine. But I have some problems with it; it could be lazyness 
on my part, but we are already discussing the topic, so let's try to 
explain it. To quote what you did say,

>I disagree.  If you are writing a GUI app, you should design an 
>architecture so that the GUI does not block for long periods of time.

I entirely agree with you. The problem is that I'm not writing a GUI 
application. I'm using PythonWin as my Python environment to do the entire 
development cycle. I think that a lot of people do the same. It's just 
better than using the interpreter in a DOS window, and Scintilla makes for 
a really nice editor. And most of my scripts aren't GUI programs. I write 
filters for log processing, data format conversion, and so on (big Radius 
log files just come to my mind :-). Some of these scripts are run in Linux, 
also. In this case, I need to put a lot of PumpWaitingMessages all over the 
script, just to make sure that I can break into if something goes wrong. If 
I don't do that, I'm simply not able to break it - clicking on the Python 
icon on the task bar does not help.

AFAIK, the problem is that my script is using all CPU time available. I 
think that the problem can't be easily solved inside PythonWin (I may be 
wrong). What is the solution? I was thinking of using explicit yield()-like 
calls to keep everything running fine, even in the middle of a CPU 
intensive process. I've checked the Windows SDK reference for some help. It 
seems that what I'm looking for is the Sleep() call:

Sleep

The Sleep function suspends the execution of the current thread for a 
specified interval.

VOID Sleep(
     DWORD dwMilliseconds        // sleep time in milliseconds
    );

Parameters

dwMilliseconds

Specifies the time, in milliseconds, for which to suspend execution. A 
value of zero causes the thread to relinquish the remainder of its time 
slice to any other thread of equal priority that is ready to run. If there 
are no other threads of equal priority ready to run, the function returns 
immediately, and the thread continues execution. A value of INFINITE causes 
an infinite delay.


Where do I need to call it? I was thinking of calling it inside Python 
itself. From time to time, a sleep() could be done, just to make sure that 
the other processes get some time to run. I've seen also the SleepEx call, 
and some other calls that apply to NT only.

I have not tested my hypothesis, so I don't know if it works. I have a big 
problem on not having MSVC installed. I do all my development on spare time 
on my home PC, and I can't afford purchasing MSVC for my personal use. I've 
installed Cygnus and MinGW, but again, that's my only computer, and I'm 
afraid of messing up my Python configuration.

I hope I have made myself clear on the intentions side. There must be other 
ways of making PythonWin more responsive changing only its internals, and 
leaving Python untouched. But I fear the problem is inherent to the 
cooperative multitasking that still exist deep inside Windows, and it may 
be need to change Python itself.

Last, some final comments on your reply:

>What happens if during your PumpMessages() call, the user actually selects 
>a different menu item, and recursively starts an operation?

As I said, I'm not writing GUI apps. My problem is trying to stop some 
simple (but long running) scripts form inside PythonWin.

>>Also, note that this call is not available under Linux, so you have to 
>>take this in account also (test the os, load pythoncom only on Win32...).
>
>So what do you suggest we use for Linux?  If we can not define a standard 
>event loop for a Windows app, I doubt we will be able to for Linux.

This problem does not apply to Linux; at least not to the same extent, 
given the different nature of either OS scheduler. But X is not saint here; 
I simply don't know how things would work out on this case. Anyway, in 
Linux I tend to use vi to edit my scripts :-)


Carlos Ribeiro






More information about the Python-list mailing list