473,323 Members | 1,560 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,323 software developers and data experts.

Counting Threads

I have a thread class and I want to be able to track its usage within
an application. FYI the class launches aplications in their own thread
when the 'launch' method is called.

That works OK

However I want to take things a bit further and my thinking was that I
could use a class parameter to do a count but I am having no luck I am
afraid.

Its 'GlobalThreadCount' I am trying to get to work. I may need to use
the globals built in - or do I.

Thanks in advance

David

#--------------------------------------------------------

from threading import Thread, Event

class ServerThreads:
"""
Wrapper for thread handling.
Thread ID 0 = Controller
Thread ID 1 = Plant Object 1
Thread ID 2 = Plant Object 2
"""

GlobalThreadCount = 0

def __init__(self):
self.Threads = {}

def launch(self, SubToLaunch, SubsArgs=(),
SubsKwargs={}, AsDeamon=True):
t = Thread(target=SubToLaunch, args = SubsArgs,
kwargs = SubsKwargs)
t.setDaemon(AsDeamon)
t.start()
self.Threads[len(self.Threads)] = t
# Stash the thread in an instance local

GlobalThreadCount += 1

def globalusagecount(self):
"""
Returns a count figure for how many
threads are running in total
using this class.
"""
return GlobalThreadCount
def stop(self,ThreadID):
t = self.Threads[ThreadID]
t.stop()
self.Threads.clear[ThreadID]

def count(self):
"""
Returns alist of how many threads are running
in the instance
"""
return len(self.Threads)

def runningkeys(self):
"""
Returns a llist of all running Keys
"""
return self.Threads.keys

def allOK(self):
"""
Returns a list of all threads that are down if any)
"""
ThreadsDown = []
for t in self.Threads:
if not self.Threads[t].isAlive:
ThreadsDown.append(t)
return ThreadsDown

Oct 27 '05 #1
9 1859
Just sorted (its always the way when you post isn't it)

But the count isn't doint what I expected. I was after a increment
after every time the class was used ireespective of instance. Instead
I get a count based on the instance usage.

Idea's anyone?

#
------------------------------------------------------------------------------------
class ServerThreads:
"""
Wrapper for thread handling.
Thread ID 0 = Controller
Thread ID 1 = Plant Object 1
Thread ID 2 = Plant Object 2
"""

GlobalThreadCount = 0

def __init__(self):
global GlobalThreadCount
self.Threads = {}
GlobalThreadCount = 0
def launch(self, SubToLaunch, SubsArgs=(), SubsKwargs={},
AsDeamon=True):
t = Thread(target=SubToLaunch, args = SubsArgs, kwargs =
SubsKwargs)
t.setDaemon(AsDeamon)
t.start()
self.Threads[len(self.Threads)] = t # Stash the
thread in an instance local

global GlobalThreadCount
GlobalThreadCount += 1
print GlobalThreadCount

def globalusagecount(self):
"""
Returns a count figure for how many threads are running in
total
usnig this class.
"""
global GlobalThreadCount
return GlobalThreadCount
def stop(self,ThreadID):
t = self.Threads[ThreadID]
t.stop()
self.Threads.clear[ThreadID]

def count(self):
"""
Returns alist of how many threads are running in the instance
"""
return len(self.Threads)

def runningkeys(self):
"""
Returns a llist of all running Keys
"""
return self.Threads.keys

def allOK(self):
"""
Returns a list of all threads that are down if any)
"""
ThreadsDown = []
for t in self.Threads:
if not self.Threads[t].isAlive:
ThreadsDown.append(t)
return ThreadsDown

Oct 27 '05 #2
Just sorted (its always the way when you post isn't it)

But the count isn't doint what I expected. I was after a increment
after every time the class was used ireespective of instance. Instead
I get a count based on the instance usage.

Idea's anyone?

#
------------------------------------------------------------------------------------
class ServerThreads:
"""
Wrapper for thread handling.
Thread ID 0 = Controller
Thread ID 1 = Plant Object 1
Thread ID 2 = Plant Object 2
"""

GlobalThreadCount = 0

def __init__(self):
global GlobalThreadCount
self.Threads = {}
GlobalThreadCount = 0
def launch(self, SubToLaunch, SubsArgs=(), SubsKwargs={},
AsDeamon=True):
t = Thread(target=SubToLaunch, args = SubsArgs, kwargs =
SubsKwargs)
t.setDaemon(AsDeamon)
t.start()
self.Threads[len(self.Threads)] = t # Stash the
thread in an instance local

global GlobalThreadCount
GlobalThreadCount += 1
print GlobalThreadCount

def globalusagecount(self):
"""
Returns a count figure for how many threads are running in
total
usnig this class.
"""
global GlobalThreadCount
return GlobalThreadCount
def stop(self,ThreadID):
t = self.Threads[ThreadID]
t.stop()
self.Threads.clear[ThreadID]

def count(self):
"""
Returns alist of how many threads are running in the instance
"""
return len(self.Threads)

def runningkeys(self):
"""
Returns a llist of all running Keys
"""
return self.Threads.keys

def allOK(self):
"""
Returns a list of all threads that are down if any)
"""
ThreadsDown = []
for t in self.Threads:
if not self.Threads[t].isAlive:
ThreadsDown.append(t)
return ThreadsDown

Oct 27 '05 #3
David Poundall wrote:
Just sorted (its always the way when you post isn't it)

But the count isn't doint what I expected. I was after a increment
after every time the class was used ireespective of instance.
I have no idea what that last sentence above means...
Instead
I get a count based on the instance usage. Idea's anyone?
Several, interspersed below:
------------------------------------------------------------------------------------
class ServerThreads:
"""
Wrapper for thread handling.
Thread ID 0 = Controller
Thread ID 1 = Plant Object 1
Thread ID 2 = Plant Object 2
"""

GlobalThreadCount = 0
Style note: using MixedCaps for variable names doesn't fit conventional
Python style. To be conventional you would use "globalThreadCount"
here, or just "threadCount" since it's no more "global" than any other
class attribute.
def __init__(self):
global GlobalThreadCount
And here you definitely don't want "global" since your GlobalThreadCount
above is *not* a Python "global". It's a class attribute, and you
should reference it as such:
self.Threads = {}
GlobalThreadCount = 0 Change to:
ServerThreads.GlobalThreadCount = 0

and access it as such in all other places inside the class.
def launch(self, SubToLaunch, SubsArgs=(), SubsKwargs={},
AsDeamon=True):
t = Thread(target=SubToLaunch, args = SubsArgs, kwargs =
SubsKwargs)
t.setDaemon(AsDeamon)
You appear to know there is a difference in spelling between these two
"demons"... but only "daemon" is correct. "Deamon" is a misspelling.
t.start()
self.Threads[len(self.Threads)] = t # Stash the
thread in an instance local

global GlobalThreadCount
GlobalThreadCount += 1
print GlobalThreadCount
Caution: if you can't guarantee that launch() will be called from only
one thread, you have a race condition here since the count could be
increased "simultaneously" from multiple threads and you won't get
reliable results. You would want to wrap it with a threading.Lock() to
protect it in that case.
def globalusagecount(self):
"""
Returns a count figure for how many threads are running in
total
usnig this class.
"""
global GlobalThreadCount
return GlobalThreadCount


Style/usage note: although as I mentioned you don't want to use "global"
variables anyway, even if you did the above line is unnecessary. You
only need to use "global" if you are going to *rebind* the global name
(i.e. assign a new value to it), not if you are merely reading the value
and returning it, as above. What you wrote would work, it's just not
needed or usual. (But, again, using a global at all is wrong anyway.)
-Peter
Oct 27 '05 #4
>> But the count isn't doint what I expected. I was after a increment
after every time the class was used ireespective of instance.

I have no idea what that last sentence above means...
On re-reading it - neither do I. Sorry about that. What I meant to
say was that I was after an increment in the count variable (the class
attribute) not an increment only within the class instances. Because
the variable was being set to zero every time the class was
instantiated I wasn't getting the true usage count.
ServerThreads.GlobalThreadCount = 0
That was what the syntax I was missing.
You appear to know there is a difference in spelling between these two
"demons"... but only "daemon" is correct. "Deamon" is a misspelling.
That one certainly slipped under the radar.
You would want to wrap it with a threading.Lock() to
protect it in that case.
Will do.
But, again, using a global at all is wrong anyway


I posted using this sytax as it was nearly working - but I knew there
was a serious clanger in the code and you pointed it out when you
identified it was the class attribute syntax I was after.

Peter, thank you for taking the time to unpick my code. It's much
apreciated. I have only been coding with Python for the past couple of
weeks and switching my brain to work with Python classes has been a bit
of a challenge. I wil re-read the document section on style tips
before I get too far into my app, as I would really like to be able to
code in a Pythonesque fashion.

David.

Oct 27 '05 #5
First time I have used thread locking. This seems to work but is it
correct?

from threading import Thread, Event, Lock
..
..
..
def launch(self, ThreadTitle, SubToLaunch, SubsArgs=(),
SubsKwargs={}, AsDaemon=True):
my_lock = Lock()
my_lock.acquire()
try:
# ---------------------
t = Thread(target=SubToLaunch, args = SubsArgs, kwargs =
SubsKwargs)
t.setDaemon(AsDaemon)
t.start()
self.Threads[len(self.Threads)] = t # Stash the
thread in an instance local
# ---------------------
ServerThreads.threadcount += 1
finally:
my_lock.release()
..
..
..

Oct 27 '05 #6
On 27 Oct 2005 16:38:36 -0700, "David Poundall" <da***@jotax.com>
declaimed the following in comp.lang.python:
First time I have used thread locking. This seems to work but is it
correct?
Not quite, since you may also want to lock it around the print
option too...

Create the lock just like you did the counter (CLASS level), then
reference it using the class name prefix in all places (you should only
need the acquire/release pair in those places, but put them around all
uses of the counter).
-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <

Oct 28 '05 #7
Sorry Denis - but could you give me an example. I can't for the life
of me see how the syntax for that would go.

Oct 28 '05 #8
On 28 Oct 2005 00:21:28 -0700, "David Poundall" <da***@jotax.com>
declaimed the following in comp.lang.python:
Sorry Denis - but could you give me an example. I can't for the life
of me see how the syntax for that would go.
I'm having to recreate your code from snippets posted over the past
few messages...

#
------------------------------------------------------------------------------------
class ServerThreads:
"""
Wrapper for thread handling.
Thread ID 0 = Controller
Thread ID 1 = Plant Object 1
Thread ID 2 = Plant Object 2
"""

GlobalThreadCount = 0
CounterLock = threading.Lock()

def __init__(self):
self.Threads = {}
# GlobalThreadCount = 0 ## unneeded here
def launch(self, SubToLaunch, SubsArgs=(), SubsKwargs={},
AsDeamon=True):
t = Thread(target=SubToLaunch, args = SubsArgs, kwargs =
SubsKwargs)
t.setDaemon(AsDeamon)
t.start()
self.Threads[len(self.Threads)] = t # Stash the
thread in an instance local

# global GlobalThreadCount ## not a global
ServerThreads.CounterLock.acquire()
ServerThreads.GlobalThreadCount += 1
print ServerThreads.GlobalThreadCount
ServerThreads.CounterLock.release()

def globalusagecount(self):
"""
Returns a count figure for how many threads are running in
total
usnig this class.
"""
# global GlobalThreadCount ##not global
ServerThreads.CounterLock.acquire()
tmp = ServerThreads.GlobalThreadCount
ServerThreads.CounterLock.release()
return tmp ##GlobalThreadCount
def stop(self,ThreadID):
t = self.Threads[ThreadID]
t.stop()
self.Threads.clear[ThreadID]

def count(self):
"""
Returns alist of how many threads are running in the instance
"""
return len(self.Threads)

def runningkeys(self):
"""
Returns a llist of all running Keys
"""
return self.Threads.keys

def allOK(self):
"""
Returns a list of all threads that are down if any)
"""
ThreadsDown = []
for t in self.Threads:
if not self.Threads[t].isAlive:
ThreadsDown.append(t)
return ThreadsDown

Hmmmm, I notice you never decrement the counter...
-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <

Oct 28 '05 #9
After much optimisation it turns out the following code does the job
for me. In the end using count didn't give me the flexibility I
needed. Instead I now name each thread and track them accordingly.
It's arguable if I need the thread locking now though, however I have
left it in to remind me of the syntax.

Thank you for posting back Dennis. Much appreciated.

# --------------------------------------------------------
class ServerThreads:
"""
Wrapper for thread handling. These threads are not
dynamic, that is to say once the application is fully
loaded the number of threads running is determined
by the size of the application - and is fixed.
"""
# --------------------- Class Attributes
# Dict holds object references to all threads
# created in the server (running or not)
thr_objects = {}
# Dict holds status of all running threads
# 0 = stopped, 1 = running
thr_running = {}
# Lock object
lck = Lock()

def launch(self, ThrName, SubToLaunch,
SubsArgs=(), SubsKwargs={}, AsDaemon=True):

""" Kickoff a thread.
thr_objects : Dictionary using ThreadTitle
as the key which holds
references to the thread object
thr_running : Dictionary holding the status
of each thread
"""
s = ServerThreads
# ---------------------
s.lck.acquire()
try:
t = Thread(name = ThrName, target=SubToLaunch,
args = SubsArgs, kwargs = SubsKwargs)
t.setDaemon(AsDaemon) # Must be set before start
s.thr_objects[ThrName] = t
s.thr_running[ThrName] = 1
if ag.gb_Appdebug: print 'Thread Started ------------- ',
ThrName
t.start()
finally:
s.lck.release()
# ---------------------

def stoprequest(self,thr_name):
""" Thread stop request - stop is pending.
Join is not needed because the main code body
drops out of the thread loops once the
thr_running = true condition has been removed."""
s = ServerThreads
# ---------------------
s.lck.acquire()
s.thr_running[thr_name] = 0 # Flag to tell running
thread to please terminate
if ag.gb_Appdebug: print 'Thread Stopping ----------- ' +
thr_name
s.lck.release()
# ---------------------

def allOK(self):
""" Returns a list of all threads that are down
when they shouldn't be (if any) """
s = ServerThreads
ThreadsDown = []
for thr_name in s.thr_objects:
if not s.thr_objects[thr_name].isAlive() and
s.thr_running[thr_name]:
# If a thread has an unscheduled stop indicate this by
returning the
# threads name otherwise return None.
ThreadsDown.append(thr_name)
return ThreadsDown

Oct 29 '05 #10

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

Similar topics

6
by: Elbert Lev | last post by:
Please correct me if I'm wrong. Python (as I understand) uses reference counting to determine when to delete the object. As soon as the object goes out of the scope it is deleted. Python does...
1
by: ash | last post by:
hi does anyone has any experience with flyweight pattern with refernce counting i want to share objects between multiple clients and want to delete the object from shared pool when the last...
32
by: William Stacey [MVP] | last post by:
Here is the link. If you find an issue or think of a feature, please post a reply or send an email. Cheers! http://www.mvptools.com/doco/csharp/semaphoredjikstra.htm -- William Stacey, MVP
1
by: j | last post by:
Hi, I've been trying to do line/character counts on documents that are being uploaded. As well as the "counting" I also have to remove certain sections from the file. So, firstly I was working...
4
by: aaronfude | last post by:
Hi, Please consider the following class (it's not really my class, but it's a good example for my question): class Vector { int myN; double *myX; Vector(int n) : myN(n), myX(new double) { }...
10
by: cj | last post by:
I'm writing a TCP/IP server app that will have many simultaneous connections. The main thread listens for new connections and starts a thread to handle each requested connection. These are short...
190
by: blangela | last post by:
If you had asked me 5 years ago about the future of C++, I would have told you that its future was assured for many years to come. Recently, I have been starting to wonder. I have been teaching...
0
by: Chris Thomasson | last post by:
Here are the pre-alpha code downloads: http://appcore.home.comcast.net/vzoom/refcount/ (both C and C++ api here...) Here is some pre-alpha documentation: ...
7
by: grabit | last post by:
Hi Peoples I have the following query to retrieve data from the db. 2 of the things it has to do is give me the date of the last post and a count of the post records in each of the categories. ...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
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...
1
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: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
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...
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
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.