Home | News | Documentation | Download

MultiThreading on Mac

Hello! I’m trying to parallelize my code - the loop over events. I want each thread to work with a different part of the tree. Before executing the macro, i loaded the library for multi-threading (gSystem ->Load(“libThread”)). If I assign the nothread with 1, the code is working, but when I assing it with 2, I receive a lot of errors.
Can anybody help me? Thank you!

void *threadfunc(void* threadid)
{
    long tid;
    tid = (long)threadid;
    Int_t end;
    if (noEv < (tid + 1) * TMath::Ceil((double)nEv/nothread)) {
        end = noEv;
    }
    else {
        end = (tid + 1) * TMath::Ceil((double)nEv/nothread);
    }
    Int_t begin = tid * TMath::Ceil((double)nEv/nothread);
      
    for(Int_t n = begin; n < end; n++) {
        
            inTree->GetEntry(n);       //after this command I get the error ( *** Break *** segmentation violation)
            ...
     }
}

int macroEx () {
    printf("Starting Thread 1\n");
   h1 = new TThread("h1", threadfunc, (void*) 0);
    h1->Run();
   printf("Starting Thread 2\n");
   h2 = new TThread("h2", threadfunc, (void*) 1);
   h2->Run();

   TThread::Ps();

   h1->Join();
   h2->Join();
   TThread::Ps();

    return 0;
}

Starting Thread 1
Starting Thread 2
     Thread                   State
  2  h2:0x7000088f9000        Running    
  1  h1:0x7000086f6000        Running    

 *** Break *** segmentation violation
[/usr/lib/system/libsystem_platform.dylib] _sigtramp (no debug info)
[<unknown binary>] (no debug info)
[/Users/antoniopetre/build/lib/libRIO.so] TDirectoryFile::Get(char const*) (no debug info)
[/Users/antoniopetre/build/lib/libTree.so] TChain::LoadTree(long long) (no debug info)
[/Users/antoniopetre/build/lib/libTree.so] TChain::GetEntry(long long, int) (no debug info)
[/Users/antoniopetre/Downloads/licenta/macroEx_C.so] anaData(void*) (no debug info)
[/Users/antoniopetre/build/lib/libThread.so] TThread::Function(void*) (no debug info)
[/usr/lib/system/libsystem_pthread.dylib] _pthread_start (no debug info)
[/usr/lib/system/libsystem_pthread.dylib] thread_start (no debug info)
Root > Warning in <TMacOSXSystem::Run>: handle uncaugth exception, terminating

 *** Break *** segmentation violation
Warning in <TMacOSXSystem::Run>: handle uncaugth exception, terminating

 *** Break *** bus error
Warning in <TMacOSXSystem::Run>: handle uncaugth exception, terminating`

Are the 2 threads accessing the same TTree and TFile objects?

Philippe.

PS. You may also need to call ROOT::EnableThreadSafety();
PPS. You may consider switching from TThread to std::thread (but then you must call ROOT::EnableThreadSafety();)

Yes, both are accessing the same TTree and TFile objects.
I’ve tried ROOT::EnableThreadSafety() and std::thread, but it still doesn’t work (and the errors are the same).
Thank you for your response!

Yes, both are accessing the same TTree and TFile objects.

Then both threads are modifying the same memory area at the same time and thus stepping on each others’ toes. To parallelize the reading the event, you could open the file twice (have 2 TFile object and 2 TTree objects) and then make sure that each thread is looking at distinct “Clusters” inside the TTree (to avoid duplicated decompression work) (See TTree::GetClusterIterator)

Depending what you need to do, it might be simpler to use RDataFrame which contains an implementation of this parallelization.

Cheers,
Philippe.