https://github.com/root-project/root
Tip revision: 0585d9f9ed27adc562735ff528f76f90ab0e0b74 authored by Axel Naumann on 24 June 2015, 12:24:33 UTC
Update ROOT version files to v6.02/12.
Update ROOT version files to v6.02/12.
Tip revision: 0585d9f
threads.cxx
#include "TApplication.h"
#include "TObject.h"
#include "TH1.h"
#include "TMath.h"
#include "TCanvas.h"
#include "TRandom.h"
#include "TThread.h"
/*
** Module name : threads
**
** Description :
** This file implements four functions, which shall perform some
** actions on objects like histograms and a canvas.
*/
// a global canvas for the drawing of histograms
TCanvas *c1;
// a pad for the histogram, will be used by thread mhs
TPad *pad1;
// a pad for the histogram, will be used by thread mhs2
TPad *pad2;
// a global histogram object, which will be accessed both by mhs and mhs1
TH1F *total0;
// thread function (filling histogram main and drawing total0 on pad1)
void *mhs(void *)
{
TThread::Printf("Start of mhs");
// change to the canvas and draw its correspondig pad 1
c1->cd();
c1->SetGrid();
pad1->Draw();
// creating a histogram is explicitly locked by a global mutex
TThread::Lock();
TH1F *main = new TH1F("main","Main contributor",100,-4,4);
TThread::UnLock();
// other operations needn't be locked
total0->Sumw2();
total0->SetMarkerStyle(21);
total0->SetMarkerSize(0.7);
main->SetFillColor(16);
// Fill histogram main randomly
gRandom->SetSeed();
const Int_t kUPDATE = 100;
Float_t xmain;
// run for a certain amount of events or
//for ( Int_t i=0; i<=100000; i++) {
// run forever
for ( Int_t i=0; ; i++) {
xmain = gRandom->Gaus(-1,1.5);
// filling of a histogram is locked to avoid data loss
TThread::Lock();
main->Fill(xmain);
total0->Fill(xmain);
TThread::UnLock();
// drawing of the histogram is locked automatically by ROOT
if (!(i%kUPDATE)) {
if (i == kUPDATE) {
pad1->cd();
total0->Draw("e1p");
}
pad1->Modified();
pad1->Update();
c1->Modified();
c1->Update();
}
// sleep for 1 ms: sleep not necessary, slows things only a bit down
// because the threads are actually doing nothing, which is eventually
// very fast ;-)
TThread::Sleep(0, 1000000);
}
TThread::Printf("End of mhs\n");
c1->Modified();
c1->Update();
return 0;
}
// thread function (filling total0)
void *mhs1(void *)
{
TThread::Printf("Start of mhs1");
// instantiation of objects has to be locked explicitly
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);
// locking avoids data loss
TThread::Lock();
s1->Fill(xs1,0.3);
s2->Fill(xs2,0.2);
total0->Fill(xs1,0.3);
total0->Fill(xs2,0.2);
TThread::UnLock();
// sleep for 6 ms: not necessary (see above)
TThread::Sleep(0, 6000000);
}
TThread::Printf("End of mhs1\n");
// wo is last draws the histogram a last time
pad1->cd();
total0->Draw("e1p");
c1->Modified();
c1->Update();
return 0;
}
// thread function: plays with its own histograms, draw on canvas in pad2
void *mhs2(void *)
{
TThread::Printf("Start of mhs2");
c1->cd();
pad2->Draw();
// Create some histograms: explicitly locked.
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();
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);
// no locking here because nobody else uses these objects
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) {
pad2->cd();
total->Draw("e1p");
}
pad2->Modified();
pad2->Update();
c1->Modified();
c1->Update();
}
// sleep for 1 ms: not necessary
TThread::Sleep(0, 1000000);
}
TThread::Printf("End of mhs2\n");
c1->Modified();
c1->Update();
return 0;
}
// thread to run Ps(): perform every 5 seconds a TThread::Ps()
void *top(void *)
{
TThread::Printf("Start of top");
for (Int_t i = 0; ;i++) {
TThread::Ps();
TThread::Sleep(5);
}
TThread::Printf("End of top");
return 0;
}
int main(int argc, char **argv)
{
TApplication theApp("h1Thread", &argc, argv);
// a global canvas for the drawing of histograms
c1 = new TCanvas("c1","The HSUM example",800,400);
// a pad for the histogram, will be used by thread mhs
pad1 = new TPad("pad1","This is pad1",0.02,0.02,0.48,0.98,33);
// a pad for the histogram, will be used by thread mhs2
pad2 = new TPad("pad2","This is pad2",0.52,0.02,0.98,0.98,33);
// a global histogram object, which will be accessed both by mhs and mhs1
total0 = new TH1F("total","This is the total distribution",100,-4,4);
// create the TThread instances
TThread *th1 = new TThread("th1",mhs);
TThread *th2 = new TThread("th2",mhs2);
TThread *th3 = new TThread("th3",mhs1);
// top thread
TThread *thp = new TThread("top",top);
th1->Run();
th2->Run();
th3->Run();
thp->Run();
printf("*** Exit the program by selecting Quit from the File menu ***\n");
theApp.Run(kTRUE);
th1->SetCancelAsynchronous();
th2->SetCancelAsynchronous();
th3->SetCancelAsynchronous();
thp->SetCancelAsynchronous();
th1->Kill();
th2->Kill();
th3->Kill();
thp->Kill();
printf("The END...\n");
return 0;
}