Hi Peter,
I had exactly the same problem, when I tried to implement threads into my
program. Here is my solution (for Linux) - but I am not computing Pi...
---File: MyThread.cxx-----------------------------------------------------------
// Example standalone application with multiple worker threads
#include <TROOT.h>
#include <TApplication.h>
#include <TThread.h>
#include <iostream.h>
////////////////////////////////////////////////////////////////////////////////
TROOT root("Threads", "Threads");
////////////////////////////////////////////////////////////////////////////////
class MThreadCalc
{
// Class which starts the threads and contains the code,
// which has to be calculated multithreaded
// public interface:
public:
MThreadCalc(Int_t NThreads);
~MThreadCalc();
Bool_t StartThreads();
void* ThreadedCalculation();
private:
Int_t m_NThreads; // Number of threads to start
Int_t m_NActiveThreads; // Number of currently active threads
Int_t m_NThreadsToActivate; // Number of threads which need to be started
Double_t m_Result; // Result of calculation
};
////////////////////////////////////////////////////////////////////////////////
void SplitCalculation(void *adr)
{
// Each new thread executes this function and
// therefore enters the MThreadCalc class again
((MThreadCalc *) adr)->ThreadedCalculation();
}
////////////////////////////////////////////////////////////////////////////////
MThreadCalc::MThreadCalc(Int_t NThreads)
{
// NThreads: NThreads for the calculation:
m_NThreads = NThreads;
m_NActiveThreads = 0;
m_NThreadsToActivate = m_NThreads;
m_Result = 0;
}
////////////////////////////////////////////////////////////////////////////////
Bool_t MThreadCalc::StartThreads()
{
Int_t i, j;
TThread *Thread;
char Text[10];
// Start the threads...
for (i = 0; i < m_NThreads; i++) {
sprintf(Text, "%d", i);
Thread = new TThread(Text,
(void(*) (void *)) &SplitCalculation,
(void*) this);
m_NActiveThreads++;
m_NThreadsToActivate--;
Thread->Run();
}
// Return to the main application loop:
return kTRUE;
}
////////////////////////////////////////////////////////////////////////////////
void* MThreadCalc::ThreadedCalculation()
{
// This method performs the calculations
// Multithreaded calculation part start
// Let's do 1/m_NThreads -part of the calculation
Int_t i;
for (i = 0; i < 10000000/m_NThreads; i += 1);
// Multithreaded calculation part end
// Sum up the result:
TThread::Lock();
m_Result += i;
if (m_NActiveThreads == 1 && m_NThreadsToActivate == 0) {
cout<<"Final Result: "<<m_Result<<endl;
} else {
cout<<"Intermediate Result: "<<m_Result<<endl;
}
TThread::UnLock();
m_NActiveThreads--;
return 0;
}
////////////////////////////////////////////////////////////////////////////////
int main(Int_t argc, Char_t **argv)
{
TApplication *ThreadApp = new TApplication("Threads", &argc, argv);
MThreadCalc *ThreadCalc = new MThreadCalc(10);
if (ThreadCalc->StartThreads() == kTRUE) {
cout<<"All threads have been started successfully!"<<endl;
}
ThreadApp->Run();
return 0;
}
////////////////////////////////////////////////////////////////////////////////
---Makefile-----------------------------------------------------------
PROGRAM = MyThreads
ROOTCFLAGS = $(shell root-config --cflags)
ROOTLIBS = $(shell root-config --libs)
ROOTGLIBS = $(shell root-config --glibs)
CXX = g++
CXXFLAGS += -g -fno-rtti -fno-exceptions -fPIC $(ROOTCFLAGS)
LD = g++
LDFLAGS = -g
LIBS = $(ROOTLIBS) -Llib -lpthread -lThread
GLIBS = $(ROOTGLIBS)
OBJS = MyThreads.o
all: $(PROGRAM)
$(PROGRAM): $(OBJS)
@$(LD) $(LDFLAGS) $(OBJS) $(SOBJS) $(CINTO) $(GLIBS) $(LIBS) -o $(PROGRAM)
@echo "$(PROGRAM) created!"
clean:
@rm -rf MyThreads
@rm -rf *.o
$(OBJS): %.o: %.cxx
@$(CXX) $(CXXFLAGS) -c $< -o $@
----------------------------------------------------------------------
The program has two unsolved problem:
* After the the method ThreadedCalculation has finished, the thread is
"finished" but not explicitly deleted.
* I am not sure if everything which needs to be "locked" is locked.
If you have/find a solution for these problems then I would be very
interest in getting them.
Hope this helps,
Andreas
PS: What about a less spartan website www.gallanis.com?
----------------------------------------------------------------------
Andreas Zoglauer
MPI fuer extraterrestrische Physik Phone: +49/89-30000-3848
Postfach 1312 Fax: +49/89-30000-3569
85741 Garching, Germany Email: zog@mpe.mpg.de
----------------------------------------------------------------------
This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:45 MET