Decisions from the 2009 Ganga dev. days in Oslo
It's agreed that the Ganga Core framework should provide a basic class for the
Thread objects which may be created in Ganga plug-ins for multi-threads operations. The basic class should implements proper methods by which the thread objects derived from the basic class can be managed and controlled centrally in a thread pool.
Implementation
Implementation is done in the
Ganga.Core.GangaThread
module containing the following classes:
-
GangaThreadPool
: a singelton maintaining a list of thread objects derived from the GangaThread
class
-
GangaThread
: the basic class extended from threading.Thread
. All thread object in Ganga should be inherited from it.
Concerning of handling parametric-sweep-like activities in multiple parallel threads, a helper module called
MTRunner
is also provided based on a pooling thread approach. The module consists of 3 main objects:
-
MTRunner
: the multi-thread activity runner
-
Algorithm
: the object for defining the runtime action
-
Data
: the data object defining the parameters or datasets the runtime action should execute on
Usage
Using the GangaThread
basic class
The following example shows how to define your own thread object extending the
GangaThread
object:
from Ganga.Core.GangaThread import GangaThread
from Ganga.Utility.logging import getLogger
class MyThread(GangaThread):
def __init__(self):
GangaThread.__init__(self, name='my_thread')
self.logger = getLogger()
def run(self):
## run a loop until the thread is notified to stop
## the "should stop" notification comes from the Ganga shutdown service
while not self.should_stop():
logger.info('still working on it ...')
## unregistered the thread from the GangaThreadPool as it's going to finish
self.unregister()
and in the main thread, just create and run
MyThread
as the following:
... ...
t = MyThread()
t.start()
... ...
Using the MTRunner
The following example demonstrates how to use
MTRunner
to say "Hello" to multiple people in parallel.
Define the runtime action to print out the customized greeting messages:
from Ganga.Core.GangaThread.MTRunner import Algorithm
class GreetingAlgorithm(Algorithm):
def process(self, item):
print 'Hello, %s!' % item
return True
Define the activity runner:
from Ganga.Core.GangaThread.MTRunner import MTRunner
class Greeter(MTRunner):
def __init__(self, numThread, keepAlive):
MTRunner.__init__(self, name='my_greeter', data=Data(collection=[]), algorithm=GreetingAlgorithm())
## specify number of agent threads to be created (i.e. number of parallel threads)
self.numThread = numThread
## specify if the agent threads should be kept alive in the background
self.keepAlive = keepAlive
## a method allow adding new people on demand
def addNewPerson(self, name):
self.addDataItem(name)
Run the
Greeter
## here we ask for 10 greeting agents and let the agents alive even there is no data to process
g = Greeter(numThread=10, keepAlive=True)
## add some initial data to be processed (people to be greeted)
g.addNewPerson(name="David")
g.addNewPerson(name="Hellen")
g.run()
## here you can run something else in your main thread and the greeter to take care of the greeting stuff
... ...
## now add more new persons
g.addNewPerson(name="Jean")
--
HurngChunLee - 12 Mar 2009