beginner, thread & else

G

Gigs_

can someone explain me this code:
----------------------------------
import thread
stdoutmutex = thread.allocate_lock()
exitmutexes = [0] * 10

def counter(myId, count):
for i in range(count):
stdoutmutex.acquire()
print '[%s] => %s' % (myId, i)
stdoutmutex.release()
exitmutexes[myId] = 1 # signal main thread

for i in range(10):
thread.start_new(counter, (i, 100))

while 0 in exitmutexes:
pass
print 'Main thread exiting.'
-----------------------------------

thread.start_new(counter, (i, 100)) is running counter function.
Is counter function and while statement executed in same time (other
things i understand, but can't get into this)?



thanks
 
D

Dennis Lee Bieber

while 0 in exitmutexes:
pass

Ugly waste of CPU time... rather than pass I'd have started the file
with an

import time

and then use

time.sleep(0)

to trigger task switching, letting the threads run.
print 'Main thread exiting.'
-----------------------------------

thread.start_new(counter, (i, 100)) is running counter function.
Is counter function and while statement executed in same time (other
things i understand, but can't get into this)?
Actually, TEN threads running the counter function, and the main
program (itself a thread) "while" loop are rapidly taking turns (that
"pass" statement results in the main thread wasting time testing the
non-mutex variable for zero entries until the interpreter determines
that it has run enough instructions, and ONLY THEN can one of the
counter threads run its code.). That "stdout" mutex means only one
counter thread can be doing the I/O, and I/O operations normally cause
task switching (that task has to block [wait] for the OS to do the
actual I/O). But because the lock is held, no other counter thread can
get into the I/O section -- the only thread that /can/ run is that cpu
waste main thread.

A version that doesn't need the I/O mutexes follows...

-=-=-=-=-=-
import threading # I don't use the more limited thread module
import Queue
import time

IOQueue = Queue.Queue()

def counter(ID, count):
for i in xrange(count):
IOQueue.put("[%s] => %s" % (ID, i))
IOQueue.put("[%s] => **************** EXITING" % ID)

start = time.clock()
for i in xrange(10):
threading.Thread(target=counter, args=(i, 200)).start()

while threading.activeCount() > 1: #main is one thread
while not IOQueue.empty():
print IOQueue.get()
time.sleep(0)

end = time.clock()

print end - start, " seconds"
-=-=-=-=-=-

Unfortunately, the use of a queue to transfer results does slow down
the execution... BUT, if you look, you'll see that these threads DID
overlap execution, compared to the locked execution that your example is
giving me (Modifying yours to show exits...)

[0] => 198
[1] => 198
[2] => 198
[3] => 198
[4] => 198
[5] => 198
[6] => 198
[7] => 198
[8] => 198
[9] => 198
[0] => 199
[1] => 199
[2] => 199
[3] => 199
[4] => 199
[5] => 199
[6] => 199
[7] => 199
[8] => 199
[9] => 199
[0] => ********** EXITING
[1] => ********** EXITING
[2] => ********** EXITING
[3] => ********** EXITING
[4] => ********** EXITING
[5] => ********** EXITING
[6] => ********** EXITING
[7] => ********** EXITING
[8] => ********** EXITING
[9] => ********** EXITING
Main thread exiting.
0.428503383074 seconds

compared to my version

[8] => **************** EXITING
[0] => 198
[3] => 194
[6] => 199
[4] => 197
[7] => 194
[5] => 196
[0] => 199
[3] => 195
[6] => **************** EXITING
[4] => 198
[7] => 195
[5] => 197
[0] => **************** EXITING
[3] => 196
[4] => 199
[7] => 196
[5] => 198
[3] => 197
[4] => **************** EXITING
[7] => 197
[5] => 199
[3] => 198
[7] => 198
[5] => **************** EXITING
[3] => 199
[7] => 199
[3] => **************** EXITING
[7] => **************** EXITING
15.7404486604 seconds
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
F

Fredrik Lundh

Gigs_ said:
can someone explain me this code

did you write that yourself, or did you find it in some book or article?

the thread module should not be used directly by application programs;
use the "threading" module instead.
stdoutmutex = thread.allocate_lock()
exitmutexes = [0] * 10

def counter(myId, count):
for i in range(count):
stdoutmutex.acquire()
print '[%s] => %s' % (myId, i)
stdoutmutex.release()
exitmutexes[myId] = 1 # signal main thread

for i in range(10):
thread.start_new(counter, (i, 100))

while 0 in exitmutexes:
pass

that's a "busy loop"; the CPU will spend all the cycles it can get
checking for the condition. that's not a good way to wait for
things.

use the "threading" module instead; by default, it waits for all threads
to finish without requiring flag lists and excessive CPU use.
print 'Main thread exiting.'

it starts a new instance of counter, in a separate thread.
Is counter function and while statement executed in same time (other
things i understand, but can't get into this)?

yes, the while loop will run in the "main" thread, in parallel with the
other threads. however, Python uses a global lock to synchronize access
to Python variables:

http://effbot.org/pyfaq/what-is-the-global-interpreter-lock.htm

so the threads in a simple program like this won't run fully in parallel
on a multi-CPU machine.

</F>
 
H

Hendrik van Rooyen

Fredrik Lundh said:
Gigs_ wrote:
the thread module should not be used directly by application programs;
use the "threading" module instead.

Ooops! - I am doing this, for long running stuff.

I was aware of threading, but I could not spot significant differences
in functionality, and thread seems to work, and so far I have not been
bitten (I think).

What are the dangers?

(Apart from the BogeyMan that might come and munch my code...)

- Hendrik
 
G

Gigs_

Fredrik said:
did you write that yourself, or did you find it in some book or article?

This is the example from programming python 2nd book, I use this just
for learning
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top