Queue.Queue-like class without the busy-wait
Antoon Pardon
apardon at forel.vub.ac.be
Tue Mar 29 07:28:21 EST 2005
Op 2005-03-29, Antoon Pardon schreef <apardon at forel.vub.ac.be>:
> Op 2005-03-29, Paul Rubin schreef <http>:
>> Antoon Pardon <apardon at forel.vub.ac.be> writes:
>>> Well have a look at what I have written over the weekend. It uses
>>> a seperate thread with one pipe for a wakeup mechanisme.
>>
>> Thanks, I'll look at it. Why don't you use usleep instead of a pipe?
>
> Because with the pipe the "sleep" can be indeterminate.
>
> The select make the thread sleep until either of the folowing
> happens.
>
> 1) A timeout, which means one of the locks has to be broken
>
> 2) A byte was received. This means a lock was tried to be
> acquired and inserted in the heap, so the timeout may
> need to be recalculated. (acquiring a lock, sends a
> byte over the pipe)
>
>> I decided over the weekend that using a separate thread with usleep is
>> the simplest thing to do in pure Python.
>
> I'm not going to call my solution simple, but it wastes very few
> cycles. if no thread is blocked on a lock, the select will just
> block until that changes. No need for some kind of polling loop.
>
And here is a small patch for it. It corrects the acquiring and
releasing of the heapmutex.
--- tlock.py 2005-03-29 14:25:09.000000000 +0200
+++ src/python/tlock.py 2005-03-29 14:25:43.000000000 +0200
@@ -67,6 +67,7 @@
heapmutex.acquire()
waketime, pl, mutex, table = heap[0]
timeout = waketime - time.time()
+ heapmutex.release()
while timeout <= 0.0:
lck = pl()
if lck is not None:
@@ -82,10 +83,11 @@
pass
finally:
mutex.release()
+ heapmutex.acquire()
heappop(heap)
waketime, pl, mutex, table = heap[0]
timeout = waketime - time.time()
- heapmutex.release()
+ heapmutex.release()
rdlst, wrlst, erlst = select([heapfd],[],[],timeout)
if rdlst:
os.read(rdlst[0],1)
@@ -107,17 +109,17 @@
for Nr in xrange(20):
try:
- print "Trying %d (loop %d)" % (Id, Nr)
+ print "Trying %2d (loop %2d)" % (Id, Nr)
T.acquire(randint(0,rg))
- print "Entering %d (loop %d)" % (Id, Nr)
+ print "Entering %2d (loop %2d)" % (Id, Nr)
sleep(randint(0,rg))
- print "Leaving %d (loop %d)" % (Id, Nr)
+ print "Leaving %2d (loop %2d)" % (Id, Nr)
T.release()
except TimeOut, ErrId:
- print "Failed %d (loop %d)" % (Id, Nr)
+ print "Failed %2d (loop %2d)" % (Id, Nr)
sleep(randint(0,rg))
- for i in xrange(rg):
+ for i in xrange(5 * rg):
th = threading.Thread(target=thrd, args=(i,))
th.start()
More information about the Python-list
mailing list