sleep and Timer

Rob Hall robhall at ii.net
Wed May 28 23:31:05 EDT 2003


"Peter Hansen" <peter at engcorp.com> wrote in message
news:3ED56C7B.B9FFBEAD at engcorp.com...
> Rob Hall wrote:
> >
> > "Peter Hansen" <peter at engcorp.com> wrote in message
> > > This way the thread wakes up every few seconds to check whether it
should
> > > terminate.  For small scripts, this might be good enough.
> >
> > I did end up implementing something like that, the trouble is, it can
still
> > take up to 5 seconds for the app to die.  I could set it to sleep for
0.5
> > seconds, but that seems to be a waste of processor time to me.
>
> Hmm... been there...  allow me to offer two other perspectives:
>
> 1. "Waste of processor time"?  What's your processor planning
> to do with all that time otherwise?  Really, "wasted" is probably
> just a scary word for a fairly minor issue.  I wouldn't worry about it.
> Besides, avoiding a 0.5 second sleep because of concerns about
> performance when you probably don't really *need* the minor bit
> of wasted time is "premature optimization" (i.e. a Bad Thing).
> If you ever notice a problem, refactor this code and make it waste
> less time, but until then you've got a working, useful program
> with less effort.
>
> 2. Five seconds isn't usually a problem, in my experience.
> Neither is two, or one, which are other values I often use for
> things like this.
>
> We've got one large app which has about seven threads running
> simultaneously, each of which wakes up about once every second to
> check whether it should terminate.  We've never really noticed
> that there was a problem, either with the one second delay being
> too long, nor with any wasted processor time.
>
> Also, if this is just a small script or minor application, you
> likely won't ever notice an issue with a 0.5 or 1.0 second wakeup.
>
> -Peter


I completely agree with you on this.  In fact, really, it's what a GUI
control does.  I suppose I was just after a 'neater' solution, and in the
mean time I wasted a few hours.

The main thing that concerned me though, was that this program will have 500
or
more threads running.  My concern was that waiting a few seconds to close
each thread down would take a while.  But this is only if I join() each
thread.  If they are all closing at once, I can probably do a 'bulk join'
like follows:

import time
import threading
import random

class test(threading.Thread):
    def __init__(self, number):
        threading.Thread.__init__(self)
        self.terminate = 0
        self.number = number

    def run(self):
        print 'Thread %d launched' % self.number
        sleepTime = random.random() * 5
        while 1:
            if self.terminate:
                break
            time.sleep(sleepTime)
        print '>>>> Thread %d terminated.' % self.number


    def quit(self):
        print 'Exiting thread %d.' % self.number
        self.terminate = 1


# Create the threads
startCreate = time.time()
threadList = []
for number in range(1,501):
    t = test(number)
    t.start()
    threadList.append(t)
endCreate = time.time()

time.sleep(1)

# Kill the threads
startKill = time.time()
for t in threadList:
    t.quit()
# Bulk join() here
for t in threadList:
    t.join()

endKill = time.time()

# Display results
timeCreate = endCreate - startCreate
timeKill = endKill - startKill
print 'Time taken to create threads is %f.' % timeCreate
print 'Time taken to kill threads is %f.' % timeKill



This method creates a random sleep up to 5 seconds.  So we don't know the
order in which they will die.

Doing it this way takes around 2.86 seconds to create the threads on my
machine and 4.78 to destroy them.

If I alter it to do a join() on each thread before going on to kill the next
thread, it takes over 300 seconds - clearly unacceptable.

However, if I comment out the print statements, it takes about 1.87 secs to
create the threads, and 3.79 to destroy them.

If  I change the random sleep time to less than 1 sec, then it only takes
0.93 seconds to destroy them - in oter words, faster than it took to create.


So really, it isn't that bad at all.  As far as wasted processing time is
concerned, the if self.terminate: construct doesn't take long and isn't a
significant drain on the CPU at all.


What I really like about this newsgroup, is the chance to verbalise a
problem and work it through with the help of others.  Often, what seems an
insurmountable problem, is just a minor issue.   But if you don't talk about
it, it will always stump you.

...It's what I find anyway.

Thanks for your help.


Rob







More information about the Python-list mailing list