Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Python: Python

Embedded Python : Why does thread lock here?

 

 

Python python RSS feed   Index | Next | Previous | View Threaded


robert.oschler at gmail

Jul 7, 2009, 11:01 AM

Post #1 of 2 (87 views)
Permalink
Embedded Python : Why does thread lock here?

I have the Python Intepreter embedded in a Delphi (Object Pascal)
program. In the Python script shown below, I have a module that
creates a thread object and starts it. The thread's run() call calls
a function called deleteOutputVariables() declared at the module
level. In my code's first incarnation the thread's run() call would
deadlock when trying to call the deleteOutputVariables() function
declared at Module level. I would never see the statement
"(deleteOutputVariables) Top of Call" printed to the screen. I now
know that I must periodically call join() with a very fast time-out to
keep Python threads happy, and that solved the problem. However I am
curious as to why it deadlocked at the deleteOutputVariables() call?
Is it because deleteOutputVariables() is declared at the module level
or because that function deletes module level variables? If so why?

The code with the relevant parts excerpted is shown below, hopefully
the indents hold up.

Thanks,
Robert

----------------------------

# MODULE: PythonThreadTest.py

# FUNCTION: Delete the variables given in the list.
def deleteOutputVariables(theModule, theOutputVariablesListOfNames):
try:
print "(deleteOutputVariables) Top of call."
for theOutputVariableName in theOutputVariablesListOfNames:
if theModule.__dict__.has_key(theOutputVariableName):
print "(Python::deleteOutputVariables) Deleting the
Output Variable named " + theOutputVariableName
del theModule.__dict__[theOutputVariableName]
except:
print "(deleteOutputVariables) Exception occurred."

# Import needed system modules
import sys, os
from threading import Thread

# ----------------- BEGIN: THREAD class to execute robodanceCommand()
class threadRun(Thread):
def __init__ (self, theJobID = None):
Thread.__init__(self)
self.jobCompleted = False
# def: __init__
def run(self):
try:
# NOTE ---> This is where the thread locks if I don't call
join(0.001) in
# my DELPHI (not Python) loop that waits on the thread to
complete. Once
# theNewThread.join() is called, execution resumes in
# deleteOutputVariables() and the thread completes.
deleteOutputVariables(Test_PYTHON, ["PyOut1"])

# Let others know we are done.
self.jobCompleted = True
except Exception, exc:
self.exceptionCaught = exc
# Let others know we are done.
self.jobCompleted = True
print("(Python::threadRun) Exception occurred.")
# end: try
# def: run()
# ----------------- END: THREAD to execute robodanceCommand()

theNewThread = None
theNewThread = threadRun("TestThread")
theNewThread.start()
--
http://mail.python.org/mailman/listinfo/python-list


gagsl-py2 at yahoo

Jul 7, 2009, 4:44 PM

Post #2 of 2 (70 views)
Permalink
Re: Embedded Python : Why does thread lock here? [In reply to]

En Tue, 07 Jul 2009 15:01:17 -0300, roschler <robert.oschler[at]gmail.com>
escribió:

> I have the Python Intepreter embedded in a Delphi (Object Pascal)
> program. In the Python script shown below, I have a module that
> creates a thread object and starts it.

Do you *execute* the module or do you *import* it?
Isn't a good idea to spawn a thread by side effect of importing a module.

> The thread's run() call calls
> a function called deleteOutputVariables() declared at the module
> level. In my code's first incarnation the thread's run() call would
> deadlock when trying to call the deleteOutputVariables() function
> declared at Module level. I would never see the statement
> "(deleteOutputVariables) Top of Call" printed to the screen. I now
> know that I must periodically call join() with a very fast time-out to
> keep Python threads happy, and that solved the problem.

What does the Delphi code? Isn't a join with a long timeout enough?

> However I am
> curious as to why it deadlocked at the deleteOutputVariables() call?
> Is it because deleteOutputVariables() is declared at the module level
> or because that function deletes module level variables? If so why?

I don't know, but you can make some experiments - move te
deleteOutputVariables as a method, or don't delete module level variables
at all, and see what happens. I'd say both factors are irrelevant.

> # FUNCTION: Delete the variables given in the list.
> def deleteOutputVariables(theModule, theOutputVariablesListOfNames):
> try:
> print "(deleteOutputVariables) Top of call."
> for theOutputVariableName in theOutputVariablesListOfNames:
> if theModule.__dict__.has_key(theOutputVariableName):
> print "(Python::deleteOutputVariables) Deleting the
> Output Variable named " + theOutputVariableName
> del theModule.__dict__[theOutputVariableName]
> except:
> print "(deleteOutputVariables) Exception occurred."

As a rule, avoid using __special__ names. There is almost never need of
using them (__init__ is a notable exception) unless you want to change
Python behaviour.
In this case:

for theOutputVariableName in theOutputVariablesListOfNames:
if hasattr(theModule, theOutputVariableName):
delattr(theModule, theOutputVariableName)

(a name like theOutputVariablesListOfNames is too long for my taste, but
that's a matter of style...)

> theNewThread = None
> theNewThread = threadRun("TestThread")

That first line is useless...

--
Gabriel Genellina

--
http://mail.python.org/mailman/listinfo/python-list

Python python RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact lists@gossamer-threads.com
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.