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