[Python-Dev] PEP needed? Introducing Tcl objects (original) (raw)

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