Why the G4AutoLock class object did not work?

the key code:

#include "G4AutoLock.hh"
namespace{
  G4Mutex RunOut=G4MUTEX_INITIALIZER;
}


void fpRunAction::EndOfRunAction(const G4Run* run)
{
G4AutoLock lock(&RunOut);
  if(run->GetRunID()==32)
  {
TCanvas* c3=new TCanvas("","",900,600);
    multi_g->Add(gr3);
    gr3->SetTitle("30MeV");
    
    multi_g->Add(gr2);
    gr2->SetTitle("20MeV");
    
    multi_g->Add(gr1);
    gr1->SetTitle("10MeV");

    multi_g->Draw("a l 3d");
    c3->Print("SingleEscapePeakEfficiency_MG.svg");
}
lock.unlock();   
}

the result with 1 thread:

the result with 12 threads:

_Geant4 Version:_11.1.1
_Operating System:_Ubuntu 20.04
_Compiler/Version:_GCC 9.4.0
_CMake Version:_3.16.3


With 12 threads, each will process a subset of the total number of events in the run, and so EndOfRunAction is called at the end of each of these “part” runs. It may be better to only plot in the main thread using the G4UserRunAction::IsMaster() member function, so something like:

  if(IsMaster() && (run->GetRunID()==32))
  {
    TCanvas* c3=new TCanvas("","",900,600);
    ...
  }

Example B1 shows a very basic case, with Example extended/runAndEvent/RE06 showing a more extensive one.

at first, i tried the codes below:

if(IsMaster() )
if (run->GetRunID()==32)
  {
    TCanvas* c3=new TCanvas("","",900,600);
    ...
  }

but the codes were not implemented.

With 1 or 12 threads, and is the condition on the run id of 32 met?

I’d suggest using a debugger or just using G4cout to output messages at certain points in/out of the conditional blocks to determine when and where things are triggered or not as the case may be, e.g.

if(IsMaster())
{
  G4cout << "On the main thread" << G4endl;
}
else
{
    G4cout << "On a worker thread" << G4endl;
}

@bmorgan , yes, when the RunID is 32, this is the condition.
thanks for your suggestion, but the most confusion to me is why the G4AutoLock class did not work.

by the way, when using the code:
“if(run->GetRunID()==32&&isMaster)”

all threads still had output.

i am sorry, it is wrong, the figure was there, and i did not delete it.
so when using the code:
“if(run->GetRunID()==32&&isMaster)”
no output produced.

Because you aren’t dealing with a mutex situation. A mutex is only required, and only has any effect, if you have one single instance (i.e., one single pointer) which is shared across multiple threads. If you look at your UserActionInitialization class you will see that you instantate separate RunAction instances for each thread. The master and each worker have completely separate pointers. Therefore, the mutex lock has nothing to do.

@mkelsey , thank you for your replying, so, how to set up a mutex situation?

That’s not really a Geant4 question. I would encourage you to read some general texts on “multithreading in C++”. You may also want to look at the multithreading section of the Geant4 documentation to see what utility classes are available to support multithreaded user coding.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.