Filling a tree during multithreading

Hi,

if you have multiple threads filling the same tree, is it necessary to Lock the other threads first?

I’m playing around using grand central dispatch on Snow Leopard. Looks good so far :slight_smile:

thanks
Peter

[quote]if you have multiple threads filling the same tree, is it necessary to Lock the other threads first? [/quote]Yes it is necessary. Calling TTree::Fill is explicitly not thread safe, neither is calling Set[Branch]Address on the tree while a different thread is executing TTree::Fill. It is usually better to fill separate (but with the same structure) TTrees in each threads (and then associated the result via a TChain).

Cheers,
Philippe.

Hi Philippe,

thanks for that - pretty much what I thought would be the case.

cheers
Peter

Hi Philippe,

if you don’t mind I have another quick question.

Is it safe to have multiple TTrees being written to a TFile at once from different threads? Let’s say I have 16 threads, and a different TTree for each thread - but they all go into one file. What about autosaving - would that get messed up?

thanks!
Peter

AutoSave is on a per tree base. But why don’t you write one Tree in one file per thread?

Rene

Hi Rene,

ok I am trying this approach now of having a different file per thread.

Within the thread, a file is created, and then a tree created. However, I am getting errors when I create the tree. I wonder is this because who ‘is’ gDirectory is getting confused as I open multiple files in multiple threads simultaneously. Is it possible to specify which TFile to create the TTree in without using TFile::cd() ?

The other approach I tried was to open the files and trees first in serial before starting the threads - but I ran into another problem there. I’m not really using threads as such, but instead apple’s grand central (which splits the job into little chunks for easy parallelization in a queue) , so I have really 5000 trees to fill into 5000 files - and there appears to be a limit on the number of files that can be opened simulateously.

thanks for any help!

[quote]Is it possible to specify which TFile to create the TTree in without using TFile::cd() ? [/quote]Yes, do:mytree->SetDirectory(myfile);.

Cheers,
Philippe.

Hi Philippe and Rene,

thanks for all your help - it seems like I am able to do what I want using TThreads but not using grand central dispatch (gcd). I show here a small loop that is performed in parallel (up to 16 times)

TFile *f = new TFile(Form(“file_%d.root”, index), “recreate”);
TTree *tree = new TTree(Form(“Tree_%d”, index), Form(“Tree_%d”, index));
NAData *data = new NAData();
tree->Branch(“NAData”, &data);
tree->SetDirectory(f);
f->Close();

where index goes from 1 to 1500 (incremented for each thread/queue) and NAData is just my own data class.

This runs absolutely fine under TThreads, but under gcd I get the following errors:
*** Break *** segmentation violation
Error in TPluginManager::FindHandler: Cannot find plugin handler for TVirtualStreamerInfo! Does $ROOTSYS/etc/plugins/TVirtualStreamerInfo exist?

Interstingly, in the gcd version, if I only try to open the TFile (and forget the rest of it), I get the following error
root.exe(82577,0x104d81000) malloc: *** error for object 0x1013ef940: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

which I also get if I run my TThreads version without calling TThread::Join (to clarify - what I do with the TThreads version is have about 100 loops where each loop Runs and Joins 16 TThread operating the function I outline above)

Fair enough I don’t expect you guys to know gcd, although I know there are a few other os x super users out there who must be thinking about looking into it

Hi Peter,

One of possible problem is that the ‘gcd’ thread like things are ‘forked’ before the meta information is completely setup. One possible trick is to have in the ‘common’ part of the job (i.e. something that is available to all ‘threads’ and executed for sure before any of the threads … in thread-land this would be in the main before the thread are started) some code that creates one of the file and one of the TTree (0 or 1 entries would be enough) to insure the setup of the meta data.

Cheers,
Philippe.