Threads and import

R

rsoh.woodhouse

Hi,

I'm trying to work out some strange (to me) behaviour that I see when
running a python script in two different ways (I've inherited some
code that needs to be maintained and integrated with another lump of
code). The sample script is:

# Sample script, simply create a new thread and run a
# regular expression match in it.
import re

import threading
class TestThread(threading.Thread):

def run(self):
print('start')
try:
re.search('mmm', 'mmmm')
except Exception, e:
print e
print('finish')

tmpThread = TestThread()
tmpThread.start()
tmpThread.join()
import time
for i in range(10):
time.sleep(0.5)
print i

# end of sample script

Now if I run this using:

$ python ThreadTest.py

then it behaves as expected, ie an output like:

start
finish
0
1
2
....

But if I run it as follows (how the inherited code was started):

$ python -c "import TestThread"

then I just get:

start


I know how to get around the problem but could someone with more
knowledge of how python works explain why this is the case?

Thanks,
Rowan
 
D

Diez B. Roggisch

Hi,

I'm trying to work out some strange (to me) behaviour that I see when
running a python script in two different ways (I've inherited some
code that needs to be maintained and integrated with another lump of
code). The sample script is:

# Sample script, simply create a new thread and run a
# regular expression match in it.
import re

import threading
class TestThread(threading.Thread):

def run(self):
print('start')
try:
re.search('mmm', 'mmmm')
except Exception, e:
print e
print('finish')

tmpThread = TestThread()
tmpThread.start()
tmpThread.join()
import time
for i in range(10):
time.sleep(0.5)
print i

# end of sample script

Now if I run this using:

$ python ThreadTest.py

then it behaves as expected, ie an output like:

start
finish
0
1
2
...

But if I run it as follows (how the inherited code was started):

$ python -c "import TestThread"

then I just get:

start


I know how to get around the problem but could someone with more
knowledge of how python works explain why this is the case?

Works for me. And I don't see any reason why it shouldn't for you -
unless you didn't show us the actual code.

Diez
 
R

rsoh.woodhouse

(e-mail address removed) schrieb:















Works for me. And I don't see any reason why it shouldn't for you -
unless you didn't show us the actual code.

Diez

Strange. That is the code exactly as I run it using python 2.4.4 2.5.1
on Ubuntu 7.10. Which version of python/what platform were you using?

Rowan
 
D

Diez B. Roggisch

Strange. That is the code exactly as I run it using python 2.4.4 2.5.1
on Ubuntu 7.10. Which version of python/what platform were you using?

mac-dir:/tmp deets$ python
Python 2.5.1 (r251:54869, Apr 18 2007, 22:08:04)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
Welcome to rlcompleter2 0.96


But I doubt this changes anything.

Diez
 
R

rsoh.woodhouse

(e-mail address removed) schrieb:


Strange. That is the code exactly as I run it using python 2.4.4 2.5.1
on Ubuntu 7.10. Which version of python/what platform were you using?

mac-dir:/tmp deets$ python
Python 2.5.1 (r251:54869, Apr 18 2007, 22:08:04)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
Welcome to rlcompleter2 0.96

But I doubt this changes anything.

Diez

Hmm. Just tested it again on OS X Python 2.4.4 and custom build of
Python 2.4.5 on Debian and get the same results as I had before.

Thanks,
Rowan
 
D

Diez B. Roggisch

(e-mail address removed) schrieb:


(e-mail address removed) schrieb:
Hi,
I'm trying to work out some strange (to me) behaviour that I see when
running a python script in two different ways (I've inherited some
code that needs to be maintained and integrated with another lump of
code). The sample script is:
# Sample script, simply create a new thread and run a
# regular expression match in it.
import re
import threading
class TestThread(threading.Thread):
def run(self):
print('start')
try:
re.search('mmm', 'mmmm')
except Exception, e:
print e
print('finish')
tmpThread = TestThread()
tmpThread.start()
tmpThread.join()
import time
for i in range(10):
time.sleep(0.5)
print i
# end of sample script
Now if I run this using:
$ python ThreadTest.py
then it behaves as expected, ie an output like:
start
finish
0
1
2
...
But if I run it as follows (how the inherited code was started):
$ python -c "import TestThread"
then I just get:
start
I know how to get around the problem but could someone with more
knowledge of how python works explain why this is the case?
Works for me. And I don't see any reason why it shouldn't for you -
unless you didn't show us the actual code.
Diez
Strange. That is the code exactly as I run it using python 2.4.4 2.5.1
on Ubuntu 7.10. Which version of python/what platform were you using?
mac-dir:/tmp deets$ python
Python 2.5.1 (r251:54869, Apr 18 2007, 22:08:04)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
Welcome to rlcompleter2 0.96

But I doubt this changes anything.

Diez

Hmm. Just tested it again on OS X Python 2.4.4 and custom build of
Python 2.4.5 on Debian and get the same results as I had before.

Are you sure that ThreadTest isn't a somewhere else installed module?
youc can use python -v to check where python gets it's files.

and how about you attach/paste the full script somewhere?

Diez
 
R

rsoh.woodhouse

(e-mail address removed) schrieb:


(e-mail address removed) schrieb:
(e-mail address removed) schrieb:
Hi,
I'm trying to work out some strange (to me) behaviour that I see when
running a python script in two different ways (I've inherited some
code that needs to be maintained and integrated with another lump of
code). The sample script is:
# Sample script, simply create a new thread and run a
# regular expression match in it.
import re
import threading
class TestThread(threading.Thread):
def run(self):
print('start')
try:
re.search('mmm', 'mmmm')
except Exception, e:
print e
print('finish')
tmpThread = TestThread()
tmpThread.start()
tmpThread.join()
import time
for i in range(10):
time.sleep(0.5)
print i
# end of sample script
Now if I run this using:
$ python ThreadTest.py
then it behaves as expected, ie an output like:
start
finish
0
1
2
...
But if I run it as follows (how the inherited code was started):
$ python -c "import TestThread"
then I just get:
start
I know how to get around the problem but could someone with more
knowledge of how python works explain why this is the case?
Works for me. And I don't see any reason why it shouldn't for you -
unless you didn't show us the actual code.
Diez
Strange. That is the code exactly as I run it using python 2.4.4 2.5.1
on Ubuntu 7.10. Which version of python/what platform were you using?
mac-dir:/tmp deets$ python
Python 2.5.1 (r251:54869, Apr 18 2007, 22:08:04)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
Welcome to rlcompleter2 0.96
for nice experiences hit <tab> multiple times
But I doubt this changes anything.
Diez
Hmm. Just tested it again on OS X Python 2.4.4 and custom build of
Python 2.4.5 on Debian and get the same results as I had before.

Are you sure that ThreadTest isn't a somewhere else installed module?
youc can use python -v to check where python gets it's files.

and how about you attach/paste the full script somewhere?

Diez

This is the full script straight from the text editor:

# START

import re

import threading
class TestThread(threading.Thread):

def run(self):
print('start')
try:
re.search('mmm', 'mmmm')
except Exception, e:
print e
print('finish')

tmpThread = TestThread()
tmpThread.start()
tmpThread.join()
import time
for i in range(10):
time.sleep(0.5)
print i

# END

In OS X I get the following output (where TestThread.py is in the
current directory):

$ python -v -c "import TestThread"
# installing zipimport hook
import zipimport # builtin
# installed zipimport hook
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
site.pyc matches /Library/Frameworks/Python.framework/Versions/2.4/lib/
python2.4/site.py
import site # precompiled from /Library/Frameworks/Python.framework/
Versions/2.4/lib/python2.4/site.pyc
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
os.pyc matches /Library/Frameworks/Python.framework/Versions/2.4/lib/
python2.4/os.py
import os # precompiled from /Library/Frameworks/Python.framework/
Versions/2.4/lib/python2.4/os.pyc
import posix # builtin
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
posixpath.pyc matches /Library/Frameworks/Python.framework/Versions/
2.4/lib/python2.4/posixpath.py
import posixpath # precompiled from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/posixpath.pyc
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
stat.pyc matches /Library/Frameworks/Python.framework/Versions/2.4/lib/
python2.4/stat.py
import stat # precompiled from /Library/Frameworks/Python.framework/
Versions/2.4/lib/python2.4/stat.pyc
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
UserDict.pyc matches /Library/Frameworks/Python.framework/Versions/2.4/
lib/python2.4/UserDict.py
import UserDict # precompiled from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/UserDict.pyc
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
copy_reg.pyc matches /Library/Frameworks/Python.framework/Versions/2.4/
lib/python2.4/copy_reg.py
import copy_reg # precompiled from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/copy_reg.pyc
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
types.pyc matches /Library/Frameworks/Python.framework/Versions/2.4/
lib/python2.4/types.py
import types # precompiled from /Library/Frameworks/Python.framework/
Versions/2.4/lib/python2.4/types.pyc
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
warnings.pyc matches /Library/Frameworks/Python.framework/Versions/2.4/
lib/python2.4/warnings.py
import warnings # precompiled from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/warnings.pyc
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
linecache.pyc matches /Library/Frameworks/Python.framework/Versions/
2.4/lib/python2.4/linecache.py
import linecache # precompiled from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/linecache.pyc
import encodings # directory /Library/Frameworks/Python.framework/
Versions/2.4/lib/python2.4/encodings
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
encodings/__init__.pyc matches /Library/Frameworks/Python.framework/
Versions/2.4/lib/python2.4/encodings/__init__.py
import encodings # precompiled from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/encodings/__init__.pyc
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
codecs.pyc matches /Library/Frameworks/Python.framework/Versions/2.4/
lib/python2.4/codecs.py
import codecs # precompiled from /Library/Frameworks/Python.framework/
Versions/2.4/lib/python2.4/codecs.pyc
import _codecs # builtin
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
encodings/aliases.pyc matches /Library/Frameworks/Python.framework/
Versions/2.4/lib/python2.4/encodings/aliases.py
import encodings.aliases # precompiled from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/encodings/aliases.pyc
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
encodings/ascii.pyc matches /Library/Frameworks/Python.framework/
Versions/2.4/lib/python2.4/encodings/ascii.py
import encodings.ascii # precompiled from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/encodings/ascii.pyc
Python 2.4.4 (#1, Oct 18 2006, 10:34:39)
[GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
import TestThread # from TestThread.py
# wrote TestThread.pyc
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
re.pyc matches /Library/Frameworks/Python.framework/Versions/2.4/lib/
python2.4/re.py
import re # precompiled from /Library/Frameworks/Python.framework/
Versions/2.4/lib/python2.4/re.pyc
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
sre.pyc matches /Library/Frameworks/Python.framework/Versions/2.4/lib/
python2.4/sre.py
import sre # precompiled from /Library/Frameworks/Python.framework/
Versions/2.4/lib/python2.4/sre.pyc
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
sre_compile.pyc matches /Library/Frameworks/Python.framework/Versions/
2.4/lib/python2.4/sre_compile.py
import sre_compile # precompiled from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/sre_compile.pyc
import _sre # builtin
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
sre_constants.pyc matches /Library/Frameworks/Python.framework/
Versions/2.4/lib/python2.4/sre_constants.py
import sre_constants # precompiled from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/sre_constants.pyc
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
sre_parse.pyc matches /Library/Frameworks/Python.framework/Versions/
2.4/lib/python2.4/sre_parse.py
import sre_parse # precompiled from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/sre_parse.pyc
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
threading.pyc matches /Library/Frameworks/Python.framework/Versions/
2.4/lib/python2.4/threading.py
import threading # precompiled from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/threading.pyc
import thread # builtin
import time # dynamically loaded from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/lib-dynload/time.so
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
traceback.pyc matches /Library/Frameworks/Python.framework/Versions/
2.4/lib/python2.4/traceback.py
import traceback # precompiled from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/traceback.pyc
import collections # dynamically loaded from /Library/Frameworks/
Python.framework/Versions/2.4/lib/python2.4/lib-dynload/collections.so
# /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/
atexit.pyc matches /Library/Frameworks/Python.framework/Versions/2.4/
lib/python2.4/atexit.py
import atexit # precompiled from /Library/Frameworks/Python.framework/
Versions/2.4/lib/python2.4/atexit.pyc
start


At which point it just hangs.

Thanks,
Rowan
 
D

Diez B. Roggisch

Python 2.4.4 (#1, Oct 18 2006, 10:34:39)
[GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
import TestThread # from TestThread.py

If I use python 2.5, this doesn't happen - instead, the module ist just run.

If I use python 2.4, it doesn't work unless I do

export PYTHONPATH=.

before I use the -m-option.

But then it works as advertised...

Diez
 
P

Peter Otten

Hi,

I'm trying to work out some strange (to me) behaviour that I see when
running a python script in two different ways (I've inherited some
code that needs to be maintained and integrated with another lump of
code). The sample script is:

# Sample script, simply create a new thread and run a
# regular expression match in it.
import re

import threading
class TestThread(threading.Thread):

def run(self):
print('start')
try:
re.search('mmm', 'mmmm')
except Exception, e:
print e
print('finish')

tmpThread = TestThread()
tmpThread.start()
tmpThread.join()
import time
for i in range(10):
time.sleep(0.5)
print i

# end of sample script

Now if I run this using:

$ python ThreadTest.py

then it behaves as expected, ie an output like:

start
finish
0
1
2
...

But if I run it as follows (how the inherited code was started):

$ python -c "import TestThread"

then I just get:

start


I know how to get around the problem but could someone with more
knowledge of how python works explain why this is the case?

You might be interested in reading

http://groups.google.com/group/comp...read/thread/01dbc25e6d1a2662/dcf55f1475dc529f

Peter
 
R

Rhamphoryncus

Hi,

I'm trying to work out some strange (to me) behaviour that I see when
running a python script in two different ways (I've inherited some
code that needs to be maintained and integrated with another lump of
code). The sample script is:

# Sample script, simply create a new thread and run a
# regular expression match in it.
import re

import threading
class TestThread(threading.Thread):

def run(self):
print('start')
try:
re.search('mmm', 'mmmm')
except Exception, e:
print e
print('finish')

tmpThread = TestThread()
tmpThread.start()
tmpThread.join()
import time
for i in range(10):
time.sleep(0.5)
print i

# end of sample script

Now if I run this using:

$ python ThreadTest.py

then it behaves as expected, ie an output like:

start
finish
0
1
2
...

But if I run it as follows (how the inherited code was started):

$ python -c "import TestThread"

then I just get:

start

I know how to get around the problem but could someone with more
knowledge of how python works explain why this is the case?

For reasons I haven't figured out, child threads always acquire the
import lock. Since the main thread is already in an import, and is
waiting for the child thread to finish, this deadlocks.

"python ThreadTest.py" doesn't deadlock because ThreadTest isn't
loaded as a module - it's loaded as a script. A script doesn't hold
the import lock while it executes.

The solution is to move all the thread spawning and whatnot into a
main() function, use the "if __name__ == '__main__': main()" trick for
when you are a script, and if a module require the caller to do
ThreadTest.main() after importing.
 

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,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top