Logo ROOT   6.16/01
Reference Guide
mt103_fillNtupleFromMultipleThreads.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_multicore
3/// \notebook
4/// Fill the same TNtuple from different threads.
5/// This tutorial illustrates the basics of how it's possible with ROOT
6/// to write simultaneously to a single output file using TBufferMerger.
7///
8/// \macro_code
9///
10/// \date May 2017
11/// \author Guilherme Amadio
12
13void mt103_fillNtupleFromMultipleThreads()
14{
15 // Avoid unnecessary output
16 gROOT->SetBatch();
17
18 // Make ROOT thread-safe
20
21 // Total number of events
22 const size_t nEntries = 65535;
23
24 // Match number of threads to what the hardware can do
25 const size_t nWorkers = 4;
26
27 // Split work in equal parts
28 const size_t nEventsPerWorker = nEntries / nWorkers;
29
30 // Create the TBufferMerger: this class orchestrates the parallel writing
31 auto fileName = "mt103_fillNtupleFromMultipleThreads.root";
32 ROOT::Experimental::TBufferMerger merger(fileName);
33
34 // Define what each worker will do
35 // We obtain from a merger a TBufferMergerFile, which is nothing more than
36 // a file which is held in memory and that flushes to the TBufferMerger its
37 // content.
38 auto work_function = [&](int seed) {
39 auto f = merger.GetFile();
40 TNtuple ntrand("ntrand", "Random Numbers", "r");
41
42 // The resetting of the kCleanup bit below is necessary to avoid leaving
43 // the management of this object to ROOT, which leads to a race condition
44 // that may cause a crash once all threads are finished and the final
45 // merge is happening
46 ntrand.ResetBit(kMustCleanup);
47
48 TRandom rnd(seed);
49 for (auto i : ROOT::TSeqI(nEntries))
50 ntrand.Fill(rnd.Gaus());
51 f->Write();
52 };
53
54 // Create worker threads
55 std::vector<std::thread> workers;
56
57 for (auto i : ROOT::TSeqI(nWorkers))
58 workers.emplace_back(work_function, i + 1); // seed==0 means random seed :)
59
60 // Make sure workers are done
61 for (auto &&worker : workers)
62 worker.join();
63}
#define f(i)
Definition: RSha256.hxx:104
@ kMustCleanup
Definition: TObject.h:343
#define gROOT
Definition: TROOT.h:410
TBufferMerger is a class to facilitate writing data in parallel from multiple threads,...
A pseudo container class which is a generator of indices.
Definition: TSeq.hxx:66
A simple TTree restricted to a list of float variables only.
Definition: TNtuple.h:28
This is the base class for the ROOT Random number generators.
Definition: TRandom.h:27
void EnableThreadSafety()
Enables the global mutex to make ROOT thread safe/aware.
Definition: TROOT.cxx:545