[Python-Dev] PEP needed? Introducing Tcl objects
Martin v. Loewis
martin@v.loewis.de
19 Feb 2002 09:43:21 +0100
Tim Peters <tim.one@comcast.net> writes:
> I believe Martin was correct in large part. The other part is that, without
> a sleep at all, we would have a pure busy loop here, competing for cycles
> non-stop with every process on the box.
Avoiding the wait to be busy is probably the #1 reason for the
sleep. The alternative to avoid a busy wait would be to do
Tcl_DoOneEvent with TCL_ALL_EVENTS, however, once Tcl becomes idle,
this will block, depriving any other thread of the opportunity to
invoke Tcl.
Of Jeff's options, invoking Tcl_SetMaxBlockTime seemed to be most
promising: I want Tcl_DoOneEvent to return after 20ms, to give other
Tcl threads a chance. So I invented the patch
Index: _tkinter.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v
retrieving revision 1.123
diff -u -r1.123 _tkinter.c
--- _tkinter.c 26 Jan 2002 20:21:50 -0000 1.123
+++ _tkinter.c 19 Feb 2002 08:34:17 -0000
@@ -1676,7 +1967,11 @@
{
int threshold = 0;
#ifdef WITH_THREAD
+ Tcl_Time blocktime = {0, 20000};
PyThreadState *tstate = PyThreadState_Get();
+ ENTER_TCL
+ Tcl_SetMaxBlockTime(&blocktime);
+ LEAVE_TCL
#endif
if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold))
@@ -1688,16 +1983,15 @@
!errorInCmd)
{
int result;
+
#ifdef WITH_THREAD
Py_BEGIN_ALLOW_THREADS
PyThread_acquire_lock(tcl_lock, 1);
tcl_tstate = tstate;
- result = Tcl_DoOneEvent(TCL_DONT_WAIT);
+ result = Tcl_DoOneEvent(0);
tcl_tstate = NULL;
PyThread_release_lock(tcl_lock);
- if (result == 0)
- Sleep(20);
Py_END_ALLOW_THREADS
#else
result = Tcl_DoOneEvent(0);
However, it does not work. The script
import Tkinter
import thread
import time
c = 0
l = Tkinter.Label(text = str(c))
l.pack()
def doit():
global c
while 1:
c+=1
l['text']=str(c)
time.sleep(1)
thread.start_new(doit, ())
l.tk.mainloop()
ought to continously increase the counter in the label (once a
second), but doesn't, atleast not on Linux, using Tcl 8.3.3. In the
strace output, it appears that it first does a select call with a
timeout, but that is followed by one without time limit before
Tcl_DoOneEvent returns.
Jeff, any ideas as to why this is happening?
Regards,
Martin