threads.cxx

Go to the documentation of this file.
00001 #include "TApplication.h"
00002 #include "TObject.h"
00003 #include "TH1.h"
00004 #include "TMath.h"
00005 #include "TCanvas.h"
00006 #include "TRandom.h"
00007 #include "TThread.h"
00008 
00009 /*
00010 ** Module name : threads
00011 **
00012 ** Description :
00013 **  This file implements four functions, which shall perform some
00014 **  actions on objects like histograms and a canvas.
00015 */
00016 
00017 
00018 // a global canvas for the drawing of histograms
00019 TCanvas *c1;
00020 // a pad for the histogram, will be used by thread mhs
00021 TPad *pad1;
00022 // a pad for the histogram, will be used by thread mhs2
00023 TPad *pad2;
00024 
00025 // a global histogram object, which will be accessed both by mhs and mhs1
00026 TH1F *total0;
00027 
00028 // thread function (filling histogram main and drawing total0 on pad1)
00029 void *mhs(void *)
00030 {
00031    TThread::Printf("Start of mhs");
00032 
00033    // change to the canvas and draw its correspondig pad 1
00034    c1->cd();
00035    c1->SetGrid();
00036    pad1->Draw();
00037 
00038    // creating a histogram is explicitely locked by a global mutex
00039    TThread::Lock();
00040    TH1F *main   = new TH1F("main","Main contributor",100,-4,4);
00041    TThread::UnLock();
00042 
00043    // other operations needn't be locked
00044    total0->Sumw2();
00045    total0->SetMarkerStyle(21);
00046    total0->SetMarkerSize(0.7);
00047    main->SetFillColor(16);
00048 
00049    // Fill histogram main randomly
00050    gRandom->SetSeed();
00051    const Int_t kUPDATE = 100;
00052    Float_t xmain;
00053    // run for a certain amount of events or
00054    //for ( Int_t i=0; i<=100000; i++) {
00055    // run forever
00056    for ( Int_t i=0; ; i++) {
00057       xmain = gRandom->Gaus(-1,1.5);
00058       // filling of a histogram is locked to avoid data loss
00059       TThread::Lock();
00060       main->Fill(xmain);
00061       total0->Fill(xmain);
00062       TThread::UnLock();
00063       // drawing of the histogram is locked automatically by ROOT
00064       if (!(i%kUPDATE)) {
00065          if (i == kUPDATE) {
00066             pad1->cd();
00067             total0->Draw("e1p");
00068          }
00069          pad1->Modified();
00070          pad1->Update();
00071          c1->Modified();
00072          c1->Update();
00073       }
00074       // sleep for 1 ms: sleep not necessary, slows things only a bit down
00075       // because the threads are actually doing nothing, which is eventually
00076       // very fast ;-)
00077       TThread::Sleep(0, 1000000);
00078    }
00079    TThread::Printf("End of mhs\n");
00080 
00081    c1->Modified();
00082    c1->Update();
00083    return 0;
00084 }
00085 
00086 // thread function (filling total0)
00087 void *mhs1(void *)
00088 {
00089    TThread::Printf("Start of mhs1");
00090 
00091    // instantiation of objects has to be locked explicitly
00092    TThread::Lock();
00093    TH1F *s1     = new TH1F("s1","This is the first signal",100,-4,4);
00094    TH1F *s2     = new TH1F("s2","This is the second signal",100,-4,4);
00095    TThread::UnLock();
00096 
00097    s1->SetFillColor(42);
00098    s2->SetFillColor(46);
00099 
00100    // Fill histograms randomly
00101    gRandom->SetSeed();
00102    Float_t xs1, xs2;
00103    //for ( Int_t i=0; i<=100000; i++) {
00104    for ( Int_t i=0; ; i++) {
00105       xs1   = gRandom->Gaus(-0.5,0.5);
00106       xs2   = gRandom->Gaus(1,0.3);
00107       // locking avoids data loss
00108       TThread::Lock();
00109       s1->Fill(xs1,0.3);
00110       s2->Fill(xs2,0.2);
00111       total0->Fill(xs1,0.3);
00112       total0->Fill(xs2,0.2);
00113       TThread::UnLock();
00114       // sleep for 6 ms: not necessary (see above)
00115       TThread::Sleep(0, 6000000);
00116    }
00117    TThread::Printf("End of mhs1\n");
00118 
00119    // wo is last draws the histogram a last time
00120    pad1->cd();
00121    total0->Draw("e1p");
00122    c1->Modified();
00123    c1->Update();
00124    return 0;
00125 }
00126 
00127 // thread function: plays with its own histograms, draw on canvas in pad2
00128 void *mhs2(void *)
00129 {
00130    TThread::Printf("Start of mhs2");
00131 
00132    c1->cd();
00133    pad2->Draw();
00134 
00135    // Create some histograms: explicitly locked.
00136    TThread::Lock();
00137    TH1F *total  = new TH1F("total2","This is the total distribution",100,-4,4);
00138    TH1F *main   = new TH1F("main2","Main contributor",100,-4,4);
00139    TH1F *s1     = new TH1F("s12","This is the first signal",100,-4,4);
00140    TH1F *s2     = new TH1F("s22","This is the second signal",100,-4,4);
00141    TThread::UnLock();
00142 
00143    total->Sumw2();
00144    total->SetMarkerStyle(21);
00145    total->SetMarkerSize(0.7);
00146    main->SetFillColor(16);
00147    s1->SetFillColor(42);
00148    s2->SetFillColor(46);
00149 
00150    // Fill histograms randomly
00151    gRandom->SetSeed();
00152    const Int_t kUPDATE = 100;
00153    Float_t xs1, xs2, xmain;
00154    // for ( Int_t i=0; i<=100000; i++) {
00155    for ( Int_t i=0; ; i++) {
00156       xmain = gRandom->Gaus(-1,1.5);
00157       xs1   = gRandom->Gaus(-0.5,0.5);
00158       xs2   = gRandom->Gaus(1,0.3);
00159       // no locking here because nobody else uses these objects
00160       main->Fill(xmain);
00161       s1->Fill(xs1,0.3);
00162       s2->Fill(xs2,0.2);
00163       total->Fill(xmain);
00164       total->Fill(xs1,0.3);
00165       total->Fill(xs2,0.2);
00166       if (!(i%kUPDATE)) {
00167          if (i == kUPDATE) {
00168             pad2->cd();
00169             total->Draw("e1p");
00170          }
00171          pad2->Modified();
00172          pad2->Update();
00173          c1->Modified();
00174          c1->Update();
00175       }
00176       // sleep for 1 ms: not necessary
00177       TThread::Sleep(0, 1000000);
00178    }
00179    TThread::Printf("End of mhs2\n");
00180    c1->Modified();
00181    c1->Update();
00182    return 0;
00183 }
00184 
00185 // thread to run Ps(): perform every 5 seconds a TThread::Ps()
00186 void *top(void *)
00187 {
00188    TThread::Printf("Start of top");
00189 
00190    for (Int_t i = 0; ;i++) {
00191       TThread::Ps();
00192       TThread::Sleep(5);
00193    }
00194    TThread::Printf("End of top");
00195    return 0;
00196 }
00197 
00198 int main(int argc, char **argv)
00199 {
00200    TApplication theApp("h1Thread", &argc, argv);
00201 
00202    // a global canvas for the drawing of histograms
00203    c1 = new TCanvas("c1","The HSUM example",800,400);
00204    // a pad for the histogram, will be used by thread mhs
00205    pad1 = new TPad("pad1","This is pad1",0.02,0.02,0.48,0.98,33);
00206    // a pad for the histogram, will be used by thread mhs2
00207    pad2 = new TPad("pad2","This is pad2",0.52,0.02,0.98,0.98,33);
00208 
00209    // a global histogram object, which will be accessed both by mhs and mhs1
00210    total0  = new TH1F("total","This is the total distribution",100,-4,4);
00211 
00212    // create the TThread instances
00213    TThread *th1 = new TThread("th1",mhs);
00214    TThread *th2 = new TThread("th2",mhs2);
00215    TThread *th3 = new TThread("th3",mhs1);
00216 
00217    // top thread
00218    TThread *thp = new TThread("top",top);
00219 
00220    th1->Run();
00221    th2->Run();
00222    th3->Run();
00223    thp->Run();
00224 
00225    printf("*** Exit the program by selecting Quit from the File menu ***\n");
00226    theApp.Run(kTRUE);
00227 
00228    th1->SetCancelAsynchronous();
00229    th2->SetCancelAsynchronous();
00230    th3->SetCancelAsynchronous();
00231    thp->SetCancelAsynchronous();
00232 
00233    th1->Kill();
00234    th2->Kill();
00235    th3->Kill();
00236    thp->Kill();
00237 
00238    printf("The END...\n");
00239 
00240    return 0;
00241 }
00242 

Generated on Tue Jul 5 15:16:27 2011 for ROOT_528-00b_version by  doxygen 1.5.1