Re: TThread

From: Marc Hemberger (M.Hemberger@gsi.de)
Date: Mon Feb 21 2000 - 13:42:26 MET


Dear Anton,

currently, as we reported on the ROOT workshop (see our PowerPoint from
the ROOT page), the TThread classes can be used on any system which are
posix compliant (it works for sure on Linux). To give you some first hint
on the status (and problems), please refer to the release notes of ROOT
(there is a link available). 

For the time being, you need to recompile ROOT to set up the Canvas
operations in threads correctly and build the libThread.so. You can set
the environment with, e.g. 

./configure linuxegcs --with-thread=/usr/lib/libpthread.so

Then recompile everything (at least for now this is necessary, but this
is subject of change).

We are currently working with TThreads in our GO4-project. We will
summarize the caveats and features and will provide a chapter to the users
manual regarding multi-threading (Damir, okay?).

For now, when you have recompiled ROOT, you may try the attached macro
mhs3.C to see some threads acting on a Canvas. I must point out that
threads are not a solution for everything. ROOT by itself is not
thread-safe and you as a developer should be really careful about what you
are planning to do in a thread. E.g. object instantiation, global pointers
etc. are dangerous!  Fons has some ideas on that and is currently working
on that. 

Greetings,

Marc


Dr. Marc Hemberger

       |\      _,,,---,,         GSI, Abteilung DV&EE
ZZZzz  /,`.-'`'    -.  ;-;;,_    Planckstr. 1 
      |,4-  ) )-,_. ,\ (  `'-' 
     '---''(_/--'  `-'\_)        64291 Darmstadt

M.Hemberger@gsi.de

** Disclaimer: My views/comments/beliefs, as strange as they are, are my own.**


On Mon, 21 Feb 2000, Anton Fokin wrote:

> Hi,
> 
> What is the status of TThread class? It is not documented in root ref. guide
> and it is not in NT root distribution, although I can see it in Solaris
> distribution. And finally, does someone has a bad/good experience with
> filling a tree in a thread? There was (is?) a problem with gFile and
> threads. Is it solved now?
> 
> Best,
> Anton
> 
> 
> 


#include "mhs3.h"

TCanvas *c1 = new TCanvas("c1","The HSUM example",1200,400);
TPad *pad1 = new TPad("pad1","This is pad1",0.02,0.02,0.48,0.83,33);
TPad *pad2 = new TPad("pad2","This is pad2",0.52,0.02,0.98,0.83,33);

TH1F *total0  = new TH1F("total","This is the total distribution",100,-4,4);

void *mhs(void *ptr)

{
//
// To see the output of this macro, click begin_html <a href="gif/hsum.gif" >here</a> end_html
//    Simple example illustrating how to use the C++ interpreter	
//    to fill histograms in a loop and show the graphics results
//
//  gROOT->Reset();

  TThread::Printf("Start of mhs %x \n" ,(int)ptr);
  
  c1->cd();
  c1->SetGrid();
  pad1->Draw();
  
  gBenchmark->Start("hsum");

  TThread::Lock();
  TH1F *main   = new TH1F("main","Main contributor",100,-4,4);
  TThread::UnLock();
  
  total0->Sumw2();   // this makes sure that the sum of squares of weights will be stored
  total0->SetMarkerStyle(21);
  total0->SetMarkerSize(0.7);
  main->SetFillColor(16);

// Fill histograms randomly
  gRandom->SetSeed();
  const Int_t kUPDATE = 100;
  Float_t xmain;
  //for ( Int_t i=0; i<=100000; i++) {
  for ( Int_t i=0;; i++) {
     xmain = gRandom->Gaus(-1,1.5);
     TThread::Lock();
     main->Fill(xmain);
     total0->Fill(xmain);
     TThread::UnLock();
     if (!(i%kUPDATE)) {
        if (i == kUPDATE) {
	   pad1->cd();
           total0->Draw("e1p");
        }
	pad1->cd();
	total0->DrawCopy("e1p");
	c1->Modified();
	c1->Update();
     }
     gSystem->Sleep(1);
  }
  TThread::Printf("End of mhs\n");

  c1->Modified();
  c1->Update();
  gBenchmark->Show("hsum");
  return 0;
}

void *mhs1(void *ptr)

{
//
// To see the output of this macro, click begin_html <a href="gif/hsum.gif" >here</a> end_html
//    Simple example illustrating how to use the C++ interpreter	
//    to fill histograms in a loop and show the graphics results
//
//  gROOT->Reset();

  TThread::Printf("Start of mhs1 %x \n" ,(int)ptr);
  
  gBenchmark->Start("hsum1");
  
  TThread::Lock();
  TH1F *s1     = new TH1F("s1","This is the first signal",100,-4,4);
  TH1F *s2     = new TH1F("s2","This is the second signal",100,-4,4);
  TThread::UnLock();
  
  s1->SetFillColor(42);
  s2->SetFillColor(46);

// Fill histograms randomly
  gRandom->SetSeed();
  Float_t xs1, xs2;
  //for ( Int_t i=0; i<=100000; i++) {
  for ( Int_t i=0;; i++) {
       xs1   = gRandom->Gaus(-0.5,0.5);
     xs2   = gRandom->Gaus(1,0.3);
     TThread::Lock();
     s1->Fill(xs1,0.3);
     s2->Fill(xs2,0.2);
     total0->Fill(xs1,0.3);
     total0->Fill(xs2,0.2);
     TThread::UnLock();
     gSystem->Sleep(6);
  }
  TThread::Printf("End of mhs1\n");

  pad1->cd();
  total0->DrawCopy("e1p");
  c1->Modified();
  c1->Update();
  gBenchmark->Show("hsum1");
  return 0;
}

void *mhs2(void *ptr)

{
//
// To see the output of this macro, click begin_html <a href="gif/hsum.gif" >here</a> end_html
//    Simple example illustrating how to use the C++ interpreter	
//    to fill histograms in a loop and show the graphics results
//
//  gROOT->Reset();


  TThread::Printf("Start of mhs2 %x \n" ,(int)ptr);

  //TThread::Lock();
  c1->cd();
  pad2->Draw();
  //TThread::UnLock();
  
  gBenchmark->Start("hsum2");

// Create some histograms.
  TThread::Lock();
  TH1F *total  = new TH1F("total2","This is the total distribution",100,-4,4);
  TH1F *main   = new TH1F("main2","Main contributor",100,-4,4);
  TH1F *s1     = new TH1F("s12","This is the first signal",100,-4,4);
  TH1F *s2     = new TH1F("s22","This is the second signal",100,-4,4);
  TThread::UnLock();

  total->Sumw2();   // this makes sure that the sum of squares of weights will be stored
  total->SetMarkerStyle(21);
  total->SetMarkerSize(0.7);
  main->SetFillColor(16);
  s1->SetFillColor(42);
  s2->SetFillColor(46);

// Fill histograms randomly
  gRandom->SetSeed();
  const Int_t kUPDATE = 100;
  Float_t xs1, xs2, xmain;
  //for ( Int_t i=0; i<=100000; i++) {
  for ( Int_t i=0; ; i++) {
       xmain = gRandom->Gaus(-1,1.5);
     xs1   = gRandom->Gaus(-0.5,0.5);
     xs2   = gRandom->Gaus(1,0.3);
     main->Fill(xmain);
     s1->Fill(xs1,0.3);
     s2->Fill(xs2,0.2);
     total->Fill(xmain);
     total->Fill(xs1,0.3);
     total->Fill(xs2,0.2);
     if (!(i%kUPDATE)) {
        if (i == kUPDATE) {
	   //TThread::Lock();
	   pad2->cd();
           total->Draw("e1p");
	   //TThread::UnLock();
        }
	//TThread::Lock();
	pad2->cd();
	total->DrawCopy("e1p");
	c1->Modified();
	c1->Update();
	//TThread::UnLock();
     }
     gSystem->Sleep(1);
  }
  TThread::Printf("End of mhs2\n");

  //TThread::Lock();
  c1->Modified();
  c1->Update();
  //TThread::UnLock();
  gBenchmark->Show("hsum2");
  return 0;
}

void *top(void* ptr)
{
//
// To see the output of this macro, click begin_html <a href="gif/hsum.gif" >here</a> end_html
//    Simple example illustrating how to use the C++ interpreter	
//    to fill histograms in a loop and show the graphics results
//
//  gROOT->Reset();

  TThread::Printf("Start of top %x\n", (int)ptr);
  
  TThread *th = (TThread *)ptr;
  
  for(Int_t i = 0; ; i++)
    { 
      TThread::Lock();
      th->Ps();
      TThread::UnLock();
      gSystem->Sleep(1000);
    }
  
  TThread::Printf("End of top\n");

  return 0;
}




#include <iostream.h>
#include "TObject.h"
#include "TClonesArray.h"
#include "TH1.h"
#include "TMath.h"
#include "TCanvas.h"
#include "TRandom.h"
#include "TThread.h"

#include "TBenchmark.h"

void *mhs(void *ptr);
void *mhs1(void *ptr);
void *mhs2(void *ptr);
void *top(void *ptr);


#ifdef __CINT__

#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;

#pragma link C++ function mhs;
#pragma link C++ function mhs1;
#pragma link C++ function mhs2;
#pragma link C++ function top;

#endif

ObjSuf        = o
SrcSuf        = cxx
ExeSuf        =
DllSuf        = so
THREADLIB      = $(THREADO)
OutPutOpt     = -o

ROOTLIBS      = -lNew -lCore -lCint -lHist -lGraf -lGraf3d -lTree \
	-lRint -lGpad -lProof -lTreePlayer -lEG -lEGPythia -lEGVenus -lRGL \
	-lGX11TTF 

# Linux with egcs
CXX           = g++
CXXFLAGS      = -g -Wall -DR__THREAD -fPIC -I$(ROOTSYS)/include
LD            = g++
LDFLAGS       = -g
SOFLAGS       = -shared
LIBS          = $(ROOTLIBS) -lm -ldl -rdynamic
GLIBS         = $(ROOTLIBS) $(ROOTGLIBS) -L/usr/X11R6/lib \
                -lXpm -lX11 -lm -ldl -rdynamic


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

THREADO        = mhs3.$(ObjSuf) \
                mhs3Dict.$(ObjSuf)

THREADS        = mhs3.$(SrcSuf) \
                mhs3Dict.$(SrcSuf)

THREADSO       = mhs3.$(DllSuf)

$(THREADSO):       $(THREADO)
		$(LD) $(SOFLAGS) $(LDFLAGS) $(THREADO) $(OutPutOpt) $(THREADSO)
		@echo "$(THREAD) done"

clean:
		@rm -f $(THREADO) $(THREADSO) *Dict.* core

.SUFFIXES: .$(SrcSuf)

###

mhs3.$(ObjSuf): mhs3.h

mhs3Dict.$(SrcSuf): mhs3.h mhs3LinkDef.h
	@echo "Generating dictionary mhs3Dict..."
	@$(ROOTSYS)/bin/rootcint -f mhs3Dict.$(SrcSuf) -c -I$(ROOTSYS) mhs3.h mhs3LinkDef.h

.$(SrcSuf).$(ObjSuf):
	$(CXX) $(CXXFLAGS) -c $<



This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:19 MET