Mailing List Archive

theads & global namespaces
Greetings all,

I am trying to share globals between threads. Is is possible for me to
share globals between threads that call functions from different
modules? Thus far I have had little success. I ask this question
because I would prefer not to put all my code in one module.

For example, I have 2 .py files: a.py and b.py. b.py contains the
function ('foo()') to be executed under the new thread, as well as the
global variable 'x'. a.py contains the call to
start_new_thread(foo,()). a.py also tries to use the global variable x.

=========================================
b.py

x = 0

def foo():
global x
x = x + 1

=========================================
a.py

from b.py import *

if __name__ == '__main__':

start_new_thread(foo, ())
while 1:
if x != 0:
print x

=========================================

So far, my code in a.py does not detect any change in x. Any
suggestions for a workaround?

Many thanks,

Taylor
theads & global namespaces [ In reply to ]
From: Taylor Anderson <andersdt@notes.cba.ufl.edu>

Greetings all,

I am trying to share globals between threads. Is is possible for me to
share globals between threads that call functions from different
modules? Thus far I have had little success. I ask this question
because I would prefer not to put all my code in one module.

For example, I have 2 .py files: a.py and b.py. b.py contains the
function ('foo()') to be executed under the new thread, as well as the
global variable 'x'. a.py contains the call to
start_new_thread(foo,()). a.py also tries to use the global variable x.

=========================================
b.py

x = 0

def foo():
global x
x = x + 1

=========================================
a.py

from b.py import *

if __name__ == '__main__':

start_new_thread(foo, ())
while 1:
if x != 0:
print x

=========================================

So far, my code in a.py does not detect any change in x. Any
suggestions for a workaround?

Many thanks,

Taylor
theads & global namespaces [ In reply to ]
Taylor Anderson <andersdt@notes.cba.ufl.edu> wrote:
: Greetings all,

: I am trying to share globals between threads. Is is possible for me to
: share globals between threads that call functions from different
: modules? Thus far I have had little success. I ask this question
: because I would prefer not to put all my code in one module.

: For example, I have 2 .py files: a.py and b.py. b.py contains the
: function ('foo()') to be executed under the new thread, as well as the
: global variable 'x'. a.py contains the call to
: start_new_thread(foo,()). a.py also tries to use the global variable x.

: =========================================
: b.py

: x = 0

: def foo():
: global x
: x = x + 1

: =========================================
: a.py

: from b.py import *

: if __name__ == '__main__':

: start_new_thread(foo, ())
: while 1:
: if x != 0:
: print x

: =========================================

: So far, my code in a.py does not detect any change in x. Any
: suggestions for a workaround?


This isn't just a threads problem, but a namespace problem.

When you create a variable, it is a name bound to an object, a reference
if you will. When you assign to that same name, often another object
will be bound. When you import using "from...import *" you create
new bindings to these objects in the new module, but not referencing the
same bindings.

What this means is, when you use "from...import...", assignments within
the module can be hidden from the calling module:

Python 1.5.2 (#14, Jun 11 1999, 16:31:09) [C] on aix4
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import foo
>>> foo.x
1.0
>>> from foo import x
>>> x
1.0
>>> x is foo.x
1
>>> foo.x = "hi"
>>> x
1.0
>>> x is foo.x
0
>>>

When foo.x was changed, x (in the local module) did not change with it,
becuase the variable "foo.x" is not the same as the variable "x". Even
if both pointed to the same object at first.

Your solution is to import "b" and reference the variable as "b.x".

[.If your system is any more complex than what you describe above, you
might have other problems with "x" within a multi-threaded environment
if you do not have some type of synchronization.]

-Arcege
theads & global namespaces [ In reply to ]
Two suggestions:
- If you're running on Solaris, the thread won't get to run
unless you give up some time. So try putting a time.sleep(.001)
into your while loop. On NT, this is not necessary (don't know
why.)
- Your thread will only increment once and then exit, so you'll
never see x>1. If you want to keep the thread running, put it in
a while loop. Make sure you give up the time slice there as well.

Roger Dev
dev@opticominc.com

In article <377A5C88.32A1FAB6@notes.cba.ufl.edu>,
andersdt@notes.cba.ufl.edu wrote:
> Greetings all,
>
> I am trying to share globals between threads. Is is possible for me
to
> share globals between threads that call functions from different
> modules? Thus far I have had little success. I ask this question
> because I would prefer not to put all my code in one module.
>
> For example, I have 2 .py files: a.py and b.py. b.py contains the
> function ('foo()') to be executed under the new thread, as well as
the
> global variable 'x'. a.py contains the call to
> start_new_thread(foo,()). a.py also tries to use the global variable
x.
>
> =========================================
> b.py
>
> x = 0
>
> def foo():
> global x
> x = x + 1
>
> =========================================
> a.py
>
> from b.py import *
>
> if __name__ == '__main__':
>
> start_new_thread(foo, ())
> while 1:
> if x != 0:
> print x
>
> =========================================
>
> So far, my code in a.py does not detect any change in x. Any
> suggestions for a workaround?
>
> Many thanks,
>
> Taylor
>
>


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
theads & global namespaces [ In reply to ]
From: rdev@my-deja.com

Two suggestions:
- If you're running on Solaris, the thread won't get to run
unless you give up some time. So try putting a time.sleep(.001)
into your while loop. On NT, this is not necessary (don't know
why.)
- Your thread will only increment once and then exit, so you'll
never see x>1. If you want to keep the thread running, put it in
a while loop. Make sure you give up the time slice there as well.

Roger Dev
dev@opticominc.com

In article <377A5C88.32A1FAB6@notes.cba.ufl.edu>,
andersdt@notes.cba.ufl.edu wrote:
> Greetings all,
>
> I am trying to share globals between threads. Is is possible for me
to
> share globals between threads that call functions from different
> modules? Thus far I have had little success. I ask this question
> because I would prefer not to put all my code in one module.
>
> For example, I have 2 .py files: a.py and b.py. b.py contains the
> function ('foo()') to be executed under the new thread, as well as
the
> global variable 'x'. a.py contains the call to
> start_new_thread(foo,()). a.py also tries to use the global variable
x.
>
> =========================================
> b.py
>
> x = 0
>
> def foo():
> global x
> x = x + 1
>
> =========================================
> a.py
>
> from b.py import *
>
> if __name__ == '__main__':
>
> start_new_thread(foo, ())
> while 1:
> if x != 0:
> print x
>
> =========================================
>
> So far, my code in a.py does not detect any change in x. Any
> suggestions for a workaround?
>
> Many thanks,
>
> Taylor
>
>


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
theads & global namespaces [ In reply to ]
Taylor Anderson wrote:
> I am trying to share globals between threads. Is is possible for me to
> share globals between threads that call functions from different
> modules?

I solved that problem by introducing a module "depository" that has my
"global" stuff that I want shared between threads. It is full of lines like
"hash_table={}" and so forth. Then in my modules I just

import depository

and down further, to access my "global" hash_table,

names=depository.hash_table.keys() # get list of keys in hash table for
expire purposes

and voila.

Yes, it works across threads. Just make sure to properly use semaphors if you
are doing operations on multiple structures (e.g., if I had two tables
"hash_table" and "hash_table_weights" and needed to keep them in sync). You
may wish to create some helper functions in your depository module to handle
the locking/setting/retrieving of such structures.

--
Eric Lee Green eric@estinc.com
SysAdmin/Software Engineer Visit our Web page:
Enhanced Software Technologies, Inc. http://www.estinc.com/
(602) 470-1115 voice (602) 470-1116 fax
theads & global namespaces [ In reply to ]
In article <377A5C88.32A1FAB6@notes.cba.ufl.edu>,
andersdt@notes.cba.ufl.edu wrote:
> Greetings all,
>
> I am trying to share globals between threads. Is is possible for me
to
> share globals between threads that call functions from different
> modules? Thus far I have had little success. I ask this question
> because I would prefer not to put all my code in one module.

Hi,

I may be teaching my granny to suck eggs here, so ignore this if it's
obvious, but in general you should not spin a thread while waiting for
another thread to do something (this doesn't fix your global problem,
it's just advice about multi-threaded programming).

All my multi-threaded experience is with java, but the classes in
Python are similar, so I'll have a go at explaining how it "should" be
done and someone can point out my errors...

(Incidentally, whether or not your program works as it is - assuming
the global access thing is fixed - will depend on the platform you
runit out, and the threads implementation used. Using conditions,
it will run on any platform).

from threading import *

globalX = 0

def test():
c = Condition()
c.acquire() # get hold of the condition
t = Thread(target=XChanger, argcs=c)
t.start()
c.wait() # this halts this thread and releases c
print globalX
c.release()

class XChanger:
def run(cond): # cond is c, passed in from the args in Thread
cond.acquire() # waits for c to be released (in c.wait() above)
globalX = globalX + 1
cond.notifyAll() # signal the other thread to restart when...
cond.release() # ...we release this

print globalX # should print 0
test() # should print 1 inside test()
print globalX # should print 1

(This is only one way of doing things - it may not even be best, but
it shows what I'm thinking of). Doug Lea has written a very good
book about threads, but it discusses Java. Because the Python threading
module is similar, you may find it useful (especially if you already
know Java).

There's also a completely different approach to using threads, which
is based on a (fairly ancient) book by Hoare called Communicating
Sequential Processes. It is more elegant, but not as popular (it's
used in occam, and there is a Java library to support it, but nothing
for Python that I know of - ask me if you're interested and I can ask
on a mailing list I am subscribed to).

Cheers,
Andrew


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
theads & global namespaces [ In reply to ]
From: Andrew Cooke <andrew@andrewcooke.free-online.co.uk>

In article <377A5C88.32A1FAB6@notes.cba.ufl.edu>,
andersdt@notes.cba.ufl.edu wrote:
> Greetings all,
>
> I am trying to share globals between threads. Is is possible for me
to
> share globals between threads that call functions from different
> modules? Thus far I have had little success. I ask this question
> because I would prefer not to put all my code in one module.

Hi,

I may be teaching my granny to suck eggs here, so ignore this if it's
obvious, but in general you should not spin a thread while waiting for
another thread to do something (this doesn't fix your global problem,
it's just advice about multi-threaded programming).

All my multi-threaded experience is with java, but the classes in
Python are similar, so I'll have a go at explaining how it "should" be
done and someone can point out my errors...

(Incidentally, whether or not your program works as it is - assuming
the global access thing is fixed - will depend on the platform you
runit out, and the threads implementation used. Using conditions,
it will run on any platform).

from threading import *

globalX = 0

def test():
c = Condition()
c.acquire() # get hold of the condition
t = Thread(target=XChanger, argcs=c)
t.start()
c.wait() # this halts this thread and releases c
print globalX
c.release()

class XChanger:
def run(cond): # cond is c, passed in from the args in Thread
cond.acquire() # waits for c to be released (in c.wait() above)
globalX = globalX + 1
cond.notifyAll() # signal the other thread to restart when...
cond.release() # ...we release this

print globalX # should print 0
test() # should print 1 inside test()
print globalX # should print 1

(This is only one way of doing things - it may not even be best, but
it shows what I'm thinking of). Doug Lea has written a very good
book about threads, but it discusses Java. Because the Python threading
module is similar, you may find it useful (especially if you already
know Java).

There's also a completely different approach to using threads, which
is based on a (fairly ancient) book by Hoare called Communicating
Sequential Processes. It is more elegant, but not as popular (it's
used in occam, and there is a Java library to support it, but nothing
for Python that I know of - ask me if you're interested and I can ask
on a mailing list I am subscribed to).

Cheers,
Andrew


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
theads & global namespaces [ In reply to ]
In article <7ldqi2$nc1$1@nnrp1.deja.com>,
rdev@my-deja.com wrote:

> - If you're running on Solaris, the thread won't get to run
> unless you give up some time. So try putting a time.sleep(.001)
> into your while loop. On NT, this is not necessary (don't know
> why.)

It works on NT, but the looping thread will eat up horrendous amounts
of CPU time (at least it does if under pthreads, don't know if Python
threads would do the same). So it's a good idea to use time.sleep
under NT as well.

--
Cliff Crawford -><-
http://www.people.cornell.edu/pages/cjc26
empty-handed I go,
)O( and behold the spade is in my hands


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
theads & global namespaces [ In reply to ]
From: ze5yr <ze5yr@my-deja.com>

In article <7ldqi2$nc1$1@nnrp1.deja.com>,
rdev@my-deja.com wrote:

> - If you're running on Solaris, the thread won't get to run
> unless you give up some time. So try putting a time.sleep(.001)
> into your while loop. On NT, this is not necessary (don't know
> why.)

It works on NT, but the looping thread will eat up horrendous amounts
of CPU time (at least it does if under pthreads, don't know if Python
threads would do the same). So it's a good idea to use time.sleep
under NT as well.

--
Cliff Crawford -><-
http://www.people.cornell.edu/pages/cjc26
empty-handed I go,
)O( and behold the spade is in my hands


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.