473,322 Members | 1,719 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

SMP, GIL and Threads

Hi,

I have an app written under version Python 2.3.5. The problem I'm
having is that it hangs on one of its threads. The thread that hangs
does updates to a standard dictionary shared with another thread that
only reads this dictionary. This app works beautifully on a single
processor boxes in my testing environment, but this problem quickly
occurs when the software runs on a dual cpu SMP blade server with
hyperthreading turned off, Windows 2003 server.

I do not bother using application level locks because I figure the GIL
is going to do the job for me, and because with one thread doing
updates and the other only reading, things remain consistent logically
for the app. The app will not have a problem if the dictionary changes
just before it does a read.

I have searched this group on this subject and seen one warning against
sharing objects between threads. I don't recall every writing a
threaded app that didn't share data between threads in some way. I've
also seen a recomendation in this list against using threads at all
with Python. I'm hoping that is an extreme view and not general wisdom
here. Python has never failed me when analysis indicated that it would
be the correct tool for the job.

Thank you for your time and attention.

Randy

Dec 16 '05 #1
11 1634
catsup wrote:
Hi,

I have an app written under version Python 2.3.5. The problem I'm
having is that it hangs on one of its threads. The thread that hangs
does updates to a standard dictionary shared with another thread that
only reads this dictionary. This app works beautifully on a single
processor boxes in my testing environment, but this problem quickly
occurs when the software runs on a dual cpu SMP blade server with
hyperthreading turned off, Windows 2003 server.
I don't see why you should get problems on SMP hardware, since the
threads are all part of the same process and should therefore (I'd have
thought) be tagged with the same processor affinity. Hence the GIL
should manage contention successfully.
I do not bother using application level locks because I figure the GIL
is going to do the job for me, and because with one thread doing
updates and the other only reading, things remain consistent logically
for the app. The app will not have a problem if the dictionary changes
just before it does a read.
I believe dictionary access is an atomic operation wrt thread switches
anyway, so I'm (again) not sure why a thread is hanging.
I have searched this group on this subject and seen one warning against
sharing objects between threads. I don't recall every writing a
threaded app that didn't share data between threads in some way. I've
also seen a recomendation in this list against using threads at all
with Python. I'm hoping that is an extreme view and not general wisdom
here. Python has never failed me when analysis indicated that it would
be the correct tool for the job.

Threads most often use Queue.Queue to communicate, precisely because its
operations are guaranteed thread-safe. Could we see some code, or do we
have to guess what the problem might be ;-) (I appreciate the code may
be too large or proprietary, but in that case could you build a test to
demonstrate the problem?).

I wouldn't worry about the "don't use threads" camp. Although there is a
lot to be said for non-blocking asynchronous operations managed by a
single thread this is by no means the only way to do things.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Dec 16 '05 #2
Steve Holden <st***@holdenweb.com> writes:
catsup wrote:
Hi,
I have an app written under version Python 2.3.5. The problem I'm
having is that it hangs on one of its threads. The thread that hangs
does updates to a standard dictionary shared with another thread that
only reads this dictionary. This app works beautifully on a single
processor boxes in my testing environment, but this problem quickly
occurs when the software runs on a dual cpu SMP blade server with
hyperthreading turned off, Windows 2003 server.

I don't see why you should get problems on SMP hardware, since the
threads are all part of the same process and should therefore (I'd
have thought) be tagged with the same processor affinity. Hence the
GIL should manage contention successfully.
I do not bother using application level locks because I figure the GIL
is going to do the job for me, and because with one thread doing
updates and the other only reading, things remain consistent logically
for the app. The app will not have a problem if the dictionary changes
just before it does a read.

I believe dictionary access is an atomic operation wrt thread
switches anyway, so I'm (again) not sure why a thread is hanging.


Well, there's at least the 'do not mutate a dictionary (or list) while
iterating over it' advice. Having one thread writing and another
reading makes it IMO impossible to avoid the conflict.

Thomas

Dec 16 '05 #3
In article <ma***************************************@python. org>,
Steve Holden <st***@holdenweb.com> wrote:
....
I don't see why you should get problems on SMP hardware, since the
threads are all part of the same process and should therefore (I'd have
thought) be tagged with the same processor affinity. Hence the GIL
should manage contention successfully.
Could you explain your thinking there? I don't know that much
about SMP. Would have thought that affinity might make a difference
with on-processor cache and so forth, but would be transparent to
applications. Are you thinking that the processor affinity would
essentially serialize execution, so SMP hardware doesn't matter
because your threads won't execute concurrently anyway?
Threads most often use Queue.Queue to communicate, precisely because its
operations are guaranteed thread-safe.


(Just thought that might bear repetition.)

Donn Cave, do**@u.washington.edu
Dec 16 '05 #4
In situations like this, you need to guard the resource with a mutex.
In Python, things like insertions are atomic but iterations are not.
Thusly, if you wrap it with a mutex, things can be made safe. I saw,
"can be", because you then have to ensure you always use the mutex to
satify your concurrent access requirements.

Greg

Dec 16 '05 #5
Yes. Iterating over a list that you concurrently update will
definately cause problems. That is not the type of "read" I am doing
in the application. My read is one key/value translation. Below is an
example of the operations I am performing to help clarify.

The update thread, running once every fifteen minutes, gathers updates
for the dictionary and applies them:

def run_thread(self):
while( not self.terminate ):
sleep(900)
for agentRec in self.agentListUpdates:
agentInfo = agentRec[1]
if agentRec[0] == 'a':
self.agentByIVRSeq[agentInfo.IVRSeq] = agentInfo #->
thread hangs here

The accessing thread takes command requests off a queue, every
half-second, placed there by an altogether different thread, and does a
lookup on this same dictionary before performing this command:

def run_thread(self):
while( not self.terminate ):
cmd = self.cmdQueue.get(False)
agentInfo = self.agentByIVRSeq[cmd[0]]
self.performCmd(cmd,agentInfo)
sleep(.5)

Dec 16 '05 #6
catsup wrote:
The accessing thread takes command requests off a queue, every
half-second, placed there by an altogether different thread, and does a
lookup on this same dictionary before performing this command:

def run_thread(self):
while( not self.terminate ):
cmd = self.cmdQueue.get(False)
agentInfo = self.agentByIVRSeq[cmd[0]]
self.performCmd(cmd,agentInfo)
sleep(.5)


You can guarantee that there will always be exactly one item available
in the Queue for this thread to pull out? Or is this a heavily edited
example, with the required "try/except Queue.Empty" handling removed for
tender minds? :-)

(Note the "exactly one", too, since having either fewer or more will be
a problem for the above code.)

-Peter

Dec 16 '05 #7
Yes. The test for Empty was edited out. There is a great deal going
on in this application, most not germane to the problem. I should
perhaps let all of you be the judge of that. Hopefully, this will be
enough to help generate ideas.

Thanks,
Randy

Dec 16 '05 #8
Donn Cave wrote:
In article <ma***************************************@python. org>,
Steve Holden <st***@holdenweb.com> wrote:
...
I don't see why you should get problems on SMP hardware, since the
threads are all part of the same process and should therefore (I'd have
thought) be tagged with the same processor affinity. Hence the GIL
should manage contention successfully.

Could you explain your thinking there? I don't know that much
about SMP. Would have thought that affinity might make a difference
with on-processor cache and so forth, but would be transparent to
applications. Are you thinking that the processor affinity would
essentially serialize execution, so SMP hardware doesn't matter
because your threads won't execute concurrently anyway?

I was just trying to underline that the separate threads won't run
concurrently, I suppose, and choosing a bad way to do it (since the
affinity need not be set and the process can freely migrate between
processors).
Threads most often use Queue.Queue to communicate, precisely because its
operations are guaranteed thread-safe.

(Just thought that might bear repetition.)

Yes!

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Dec 16 '05 #9
In article <11**********************@z14g2000cwz.googlegroups .com>,
catsup <ra**********@gmail.com> wrote:

I have an app written under version Python 2.3.5. The problem I'm
having is that it hangs on one of its threads. The thread that hangs
does updates to a standard dictionary shared with another thread that
only reads this dictionary. This app works beautifully on a single
processor boxes in my testing environment, but this problem quickly
occurs when the software runs on a dual cpu SMP blade server with
hyperthreading turned off, Windows 2003 server.
Hrm. This is either a Python bug or a bug in your application; I'd bet
on the latter, but the former is possible. (That is, there have been
bugs in previous versions of Python that were at least theoretically
stimulatable on single-CPU machines but in practice only showed up with
SMP machines.)

To find out which this is, you need to provide a reasonably small chunk
of code that demonstrates the problem. Until you prove otherwise, we'll
have to assume that it's a bug in your code, because many other people
are running threaded applications just fine. You might check the dev
logs and see if any thread bugs were fixed for 2.4 (or just try using
2.4 to see whether that helps).
I do not bother using application level locks because I figure the GIL
is going to do the job for me, and because with one thread doing
updates and the other only reading, things remain consistent logically
for the app. The app will not have a problem if the dictionary changes
just before it does a read.
This is usually safe.
I have searched this group on this subject and seen one warning against
sharing objects between threads. I don't recall every writing a
threaded app that didn't share data between threads in some way. I've
also seen a recomendation in this list against using threads at all
with Python. I'm hoping that is an extreme view and not general wisdom
here. Python has never failed me when analysis indicated that it would
be the correct tool for the job.


What the warning actually means is that the only shared object between
threads should be a Queue; you pass other objects between threads using
the Queue, so that only one thread at a time uses the non-Queue objects.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"Don't listen to schmucks on USENET when making legal decisions. Hire
yourself a competent schmuck." --USENET schmuck (aka Robert Kern)
Dec 16 '05 #10
It was actually quite a minor adjustment in the application to follow
the oft repeated advice here on this subject to share only the Queue
object between threads. Making the update of the dictionary just
another queued command request caused both the dictionary read and
write to be performed by the same thread. This seems to have
eliminated the problem.

Thank you all for your thoughtful comments.

Randy

Dec 17 '05 #11
In article <11**********************@g14g2000cwa.googlegroups .com>,
catsup <ra**********@gmail.com> wrote:

It was actually quite a minor adjustment in the application to follow
the oft repeated advice here on this subject to share only the
Queue object between threads. Making the update of the dictionary
just another queued command request caused both the dictionary read
and write to be performed by the same thread. This seems to have
eliminated the problem.


Great!
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"Don't listen to schmucks on USENET when making legal decisions. Hire
yourself a competent schmuck." --USENET schmuck (aka Robert Kern)
Dec 17 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Ronan Viernes | last post by:
Hi, I have created a python script (see below) to count the maximum number of threads per process (by starting new threads continuously until it breaks). ###### #testThread.py import...
0
by: Al Tobey | last post by:
I was building perl 5.8.2 on RedHat Enterprise Linux 3.0 (AS) today and noticed that it included in it's ccflags "-DTHREADS_HAVE_PIDS." I am building with -Dusethreads. With newer Linux...
6
by: m | last post by:
Hello, I have an application that processes thousands of files each day. The filenames and various related file information is retrieved, related filenames are associate and placed in a linked...
34
by: Kovan Akrei | last post by:
Hi, I would like to know how to reuse an object of a thread (if it is possible) in Csharp? I have the following program: using System; using System.Threading; using System.Collections; ...
3
by: bygandhi | last post by:
Hi - I am writing a service which will check a process and its threads for their state ( alive or dead ). The process has 5 .net managed threads created using thread.start and each have been...
10
by: [Yosi] | last post by:
I would like to know how threads behavior in .NET . When an application create 4 threads for example start all of them, the OS task manager will execute all 4 thread in deterministic order manes,...
6
by: RahimAsif | last post by:
Hi guys, I would like some advice on thread programming using C#. I am writing an application that communicates with a panel over ethernet, collects data and writes it to a file. The way the...
3
by: mjheitland | last post by:
Hi, I like to know how many threads are used by a Threading.Timer object. When I create a Threading.Timer object calling a short running method every 5 seconds I expected to have one additional...
10
by: Darian | last post by:
Is there a way to find all the thread names that are running in a project? For example, if I have 5 threads T1, T2, T3, T4, T5...and T2, T4, and T5 are running...I want to be able to know that...
4
by: tdahsu | last post by:
All, I'd appreciate any help. I've got a list of files in a directory, and I'd like to iterate through that list and process each one. Rather than do that serially, I was thinking I should...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.