Geant4 가이드

본 토픽은 현재 준비중입니다. 공동공부에 참여하시면 완성 되었을 때 알려드립니다.

Mutex

OTPrimaryGeneratorAction 변경점

이제 OTPrimaryGeneratorAction은 이벤트 생성의 직접적인 의무를 모두 넘겨주었기 때문에 이벤트를 생성해야 하는 때에 OTMasterRunAction::GeneratePrimareis(G4Event *) 함수를 불러오는 역할만 남았다. 그렇기 때문에 기존 코드는 지우고 아래와 같이 적을 수 있다. OTPrimaryGeneratorAction(소스헤더)

void OTPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
  OTMasterRunAction *runAction = (OTMasterRunAction *) G4MTRunManager::GetMasterRunManager() -> GetUserRunAction();
  runAction -> GeneratePrimaries(anEvent);
}

그런데 여기서 주의할점이 있다. 앞서 스레드 안정성에 대해서 이야기를 하고 해결하지 않았지만 그 부분을 여기서 해결하도록 한다. 문제를 확하게 적자면, 이벤트 파일을 읽는 작업은 동시에 두 스레드가 요청하였을 때 충돌이 일어나면 프로그램이 멈추거나 멈추지 않더라도 결과를 믿을 수 없게 된다. 따라서 이 작업은 한번에 한 스레드만 허용하도록 해야 한다. 이런 문제는 mutex로 해결할 수 있다.

Mutex

Mutex란 Mutual Exclusive의 약자로, 번역하면 상호 배제라는 뜻으로 특정 역역에서 한번에 하나의 스레드만 진행을 허용하도록 하는 기술이다. 바로 OTPrimaryGeneratorAction에서 필요한 기능이다. Geant4에서도 자체적으로 이 기능을 지원하는데 바로 아래과 같이 적으면 된다.

...
#include "G4AutoLock.hh"

namespace { G4Mutex aMutex = G4MUTEX_INITIALIZER; }

...

void OTPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
  G4AutoLock lock(&aMutex);

  OTMasterRunAction *runAction = (OTMasterRunAction *) G4MTRunManager::GetMasterRunManager() -> GetUserRunAction();
  runAction -> GeneratePrimaries(anEvent);
}

기존의 코드에서 헤더 "G4AutoLck.hh"와 바로 아래에

namespace { G4Mutex aMtex = G$MUTEX_INITIALIZER; }

와 같이 적는다. 그리고 스레드가 한번에 하나만 허용되는 영역 앞에

G4AutoLock lock(&aMutex)

와 같이 적으면 해당 영역은 한번에 한 스레드만 통과할 수 있다. 예를 들어 1번 스레드가 이 영역을 통과하려 할 때 이미 0번 스레드가 사용중이라면 1번 스레드는 0번 스레드가 영역을 빠져나갈 때 까지 기다려야 한다.

주의) G4Mutex와 G4AutoLock의 기능은 std::mutex와 사용방법이 다르다. 

댓글

댓글 본문
버전 관리
ejungwoo
현재 버전
선택 버전
graphittie 자세히 보기