ROOT logo

From $ROOTSYS/tutorials/thread/threadsh2.C

//+ Example of a simple script creating 2 threads each with one canvas.
// This script can only be executed via ACliC .x threadsh2.C++.
// The canvases are saved in a animated gif file.

#include "TROOT.h"
#include "TCanvas.h"
#include "TRootCanvas.h"
#include "TFrame.h"
#include "TH1F.h"
#include "TRandom.h"
#include "TThread.h"
#include "TMethodCall.h"

TCanvas *c1, *c2;
TH1F    *hpx, *total, *hmain, *s1, *s2;
TThread *thread1, *thread2, *threadj;
Bool_t   finished;

void *handle1(void *)
{
   int nfills = 10000;
   int upd = 500;

   TThread::Lock();
   hpx = new TH1F("hpx", "This is the px distribution", 100, -4, 4);
   hpx->SetFillColor(48);
   TThread::UnLock();
   Float_t px, py, pz;
   gRandom->SetSeed();
   for (Int_t i = 0; i < nfills; i++) {
      gRandom->Rannor(px, py);
      pz = px*px + py*py;
      hpx->Fill(px);
      if (i && (i%upd) == 0) {
         if (i == upd) {
            c1->cd();
            hpx->Draw();
         }
         c1->Modified();
         c1->Update();
         gSystem->Sleep(10);
         TMethodCall c(c1->IsA(), "Print", "");
         void *arr[4];
         arr[1] = &c;
         arr[2] = (void *)c1;
         arr[3] = (void*)"\"hpxanim.gif+50\"";
         (*gThreadXAR)("METH", 4, arr, NULL);
      }
   }
   c1->Modified();
   c1->Update();
   TMethodCall c(c1->IsA(), "Print", "");
   void *arr[4];
   arr[1] = &c;
   arr[2] = (void *)c1;
   arr[3] = (void*)"\"hpxanim.gif++\"";
   (*gThreadXAR)("METH", 4, arr, NULL);
   return 0;
}

void *handle2(void *)
{
   int nfills = 10000;
   int upd = 500;

   TThread::Lock();
   total  = new TH1F("total","This is the total distribution",100,-4,4);
   hmain  = new TH1F("hmain","Main contributor",100,-4,4);
   s1     = new TH1F("s1","This is the first signal",100,-4,4);
   s2     = new TH1F("s2","This is the second signal",100,-4,4);
   total->Sumw2();   // this makes sure that the sum of squares of weights will be stored
   total->SetMarkerStyle(21);
   total->SetMarkerSize(0.7);
   hmain->SetFillColor(16);
   s1->SetFillColor(42);
   s2->SetFillColor(46);
   TThread::UnLock();
   Float_t xs1, xs2, xmain;
   gRandom->SetSeed();
   for (Int_t i = 0; i < nfills; i++) {
      xmain = gRandom->Gaus(-1,1.5);
      xs1   = gRandom->Gaus(-0.5,0.5);
      xs2   = gRandom->Landau(1,0.15);
      hmain->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 && (i%upd) == 0) {
         if (i == upd) {
            c2->cd();
            total->Draw("e1p");
            hmain->Draw("same");
            s1->Draw("same");
            s2->Draw("same");
         }
         c2->Modified();
         c2->Update();
         gSystem->Sleep(10);
         TMethodCall c(c2->IsA(), "Print", "");
         void *arr[4];
         arr[1] = &c;
         arr[2] = (void *)c2;
         arr[3] = (void*)"\"hsumanim.gif+50\"";
         (*gThreadXAR)("METH", 4, arr, NULL);
      }
   }
   total->Draw("sameaxis"); // to redraw axis hidden by the fill area
   c2->Modified();
   c2->Update();
   // make infinite animation by adding "++" to the file name
   TMethodCall c(c2->IsA(), "Print", "");
   void *arr[4];
   arr[1] = &c;
   arr[2] = (void *)c2;
   arr[3] = (void*)"\"hsumanim.gif++\"";
   (*gThreadXAR)("METH", 4, arr, NULL);
   return 0;
}

void *joiner(void *)
{
   thread1->Join();
   thread2->Join();

   finished = kTRUE;

   return 0;
}

void tryclosing(Int_t id)
{
   // allow to close the canvas only after the threads are done
   if (!finished) return;
   if (id == 1) ((TRootCanvas *)c1->GetCanvasImp())->CloseWindow();
   else if (id == 2) ((TRootCanvas *)c2->GetCanvasImp())->CloseWindow();
}

void threadsh2()
{
#ifdef __CINT__
   printf("This script can only be executed via ACliC: .x threadsh2.C++\n");
   return;
#endif

   c1 = new TCanvas("c1","Dynamic Filling Example", 100, 30, 400, 300);
   c1->SetFillColor(42);
   c1->GetFrame()->SetFillColor(21);
   c1->GetFrame()->SetBorderSize(6);
   c1->GetFrame()->SetBorderMode(-1);
   // connect to the CloseWindow() signal and prevent to close the canvas 
   // while the thread is running
   ((TRootCanvas *)c1->GetCanvasImp())->Connect("CloseWindow()", 0, 0, 
                                                "tryclosing(Int_t=1)");
   ((TRootCanvas *)c1->GetCanvasImp())->DontCallClose();

   c2 = new TCanvas("c2","Dynamic Filling Example", 515, 30, 400, 300);
   c2->SetGrid();
   // connect to the CloseWindow() signal and prevent to close the canvas 
   // while the thread is running
   ((TRootCanvas *)c2->GetCanvasImp())->Connect("CloseWindow()", 0, 0, 
                                                "tryclosing(Int_t=2)");
   ((TRootCanvas *)c2->GetCanvasImp())->DontCallClose();

   finished = kFALSE;
   //gDebug = 1;
   gSystem->Unlink("hpxanim.gif");
   gSystem->Unlink("hsumanim.gif");

   printf("Starting Thread 0\n");
   thread1 = new TThread("t0", handle1, (void*) 0);
   thread1->Run();
   printf("Starting Thread 1\n");
   thread2 = new TThread("t1", handle2, (void*) 1);
   thread2->Run();
   printf("Starting Joiner Thread \n");
   threadj = new TThread("t4", joiner, (void*) 3);
   threadj->Run();

   TThread::Ps();

   while (!finished) {
      gSystem->Sleep(100);
      gSystem->ProcessEvents();
   }

   threadj->Join();
   TThread::Ps();

   delete thread1;
   delete thread2;
   delete threadj;
}
 threadsh2.C:1
 threadsh2.C:2
 threadsh2.C:3
 threadsh2.C:4
 threadsh2.C:5
 threadsh2.C:6
 threadsh2.C:7
 threadsh2.C:8
 threadsh2.C:9
 threadsh2.C:10
 threadsh2.C:11
 threadsh2.C:12
 threadsh2.C:13
 threadsh2.C:14
 threadsh2.C:15
 threadsh2.C:16
 threadsh2.C:17
 threadsh2.C:18
 threadsh2.C:19
 threadsh2.C:20
 threadsh2.C:21
 threadsh2.C:22
 threadsh2.C:23
 threadsh2.C:24
 threadsh2.C:25
 threadsh2.C:26
 threadsh2.C:27
 threadsh2.C:28
 threadsh2.C:29
 threadsh2.C:30
 threadsh2.C:31
 threadsh2.C:32
 threadsh2.C:33
 threadsh2.C:34
 threadsh2.C:35
 threadsh2.C:36
 threadsh2.C:37
 threadsh2.C:38
 threadsh2.C:39
 threadsh2.C:40
 threadsh2.C:41
 threadsh2.C:42
 threadsh2.C:43
 threadsh2.C:44
 threadsh2.C:45
 threadsh2.C:46
 threadsh2.C:47
 threadsh2.C:48
 threadsh2.C:49
 threadsh2.C:50
 threadsh2.C:51
 threadsh2.C:52
 threadsh2.C:53
 threadsh2.C:54
 threadsh2.C:55
 threadsh2.C:56
 threadsh2.C:57
 threadsh2.C:58
 threadsh2.C:59
 threadsh2.C:60
 threadsh2.C:61
 threadsh2.C:62
 threadsh2.C:63
 threadsh2.C:64
 threadsh2.C:65
 threadsh2.C:66
 threadsh2.C:67
 threadsh2.C:68
 threadsh2.C:69
 threadsh2.C:70
 threadsh2.C:71
 threadsh2.C:72
 threadsh2.C:73
 threadsh2.C:74
 threadsh2.C:75
 threadsh2.C:76
 threadsh2.C:77
 threadsh2.C:78
 threadsh2.C:79
 threadsh2.C:80
 threadsh2.C:81
 threadsh2.C:82
 threadsh2.C:83
 threadsh2.C:84
 threadsh2.C:85
 threadsh2.C:86
 threadsh2.C:87
 threadsh2.C:88
 threadsh2.C:89
 threadsh2.C:90
 threadsh2.C:91
 threadsh2.C:92
 threadsh2.C:93
 threadsh2.C:94
 threadsh2.C:95
 threadsh2.C:96
 threadsh2.C:97
 threadsh2.C:98
 threadsh2.C:99
 threadsh2.C:100
 threadsh2.C:101
 threadsh2.C:102
 threadsh2.C:103
 threadsh2.C:104
 threadsh2.C:105
 threadsh2.C:106
 threadsh2.C:107
 threadsh2.C:108
 threadsh2.C:109
 threadsh2.C:110
 threadsh2.C:111
 threadsh2.C:112
 threadsh2.C:113
 threadsh2.C:114
 threadsh2.C:115
 threadsh2.C:116
 threadsh2.C:117
 threadsh2.C:118
 threadsh2.C:119
 threadsh2.C:120
 threadsh2.C:121
 threadsh2.C:122
 threadsh2.C:123
 threadsh2.C:124
 threadsh2.C:125
 threadsh2.C:126
 threadsh2.C:127
 threadsh2.C:128
 threadsh2.C:129
 threadsh2.C:130
 threadsh2.C:131
 threadsh2.C:132
 threadsh2.C:133
 threadsh2.C:134
 threadsh2.C:135
 threadsh2.C:136
 threadsh2.C:137
 threadsh2.C:138
 threadsh2.C:139
 threadsh2.C:140
 threadsh2.C:141
 threadsh2.C:142
 threadsh2.C:143
 threadsh2.C:144
 threadsh2.C:145
 threadsh2.C:146
 threadsh2.C:147
 threadsh2.C:148
 threadsh2.C:149
 threadsh2.C:150
 threadsh2.C:151
 threadsh2.C:152
 threadsh2.C:153
 threadsh2.C:154
 threadsh2.C:155
 threadsh2.C:156
 threadsh2.C:157
 threadsh2.C:158
 threadsh2.C:159
 threadsh2.C:160
 threadsh2.C:161
 threadsh2.C:162
 threadsh2.C:163
 threadsh2.C:164
 threadsh2.C:165
 threadsh2.C:166
 threadsh2.C:167
 threadsh2.C:168
 threadsh2.C:169
 threadsh2.C:170
 threadsh2.C:171
 threadsh2.C:172
 threadsh2.C:173
 threadsh2.C:174
 threadsh2.C:175
 threadsh2.C:176
 threadsh2.C:177
 threadsh2.C:178
 threadsh2.C:179
 threadsh2.C:180
 threadsh2.C:181
 threadsh2.C:182
 threadsh2.C:183
 threadsh2.C:184
 threadsh2.C:185
 threadsh2.C:186
 threadsh2.C:187
 threadsh2.C:188
 threadsh2.C:189
 threadsh2.C:190
 threadsh2.C:191
 threadsh2.C:192
 threadsh2.C:193
 threadsh2.C:194
 threadsh2.C:195