Re: [ROOT] Standalone version of CalcPiThread

From: Andreas Zoglauer (zog@mpe.mpg.de)
Date: Mon May 14 2001 - 05:17:16 MEST


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