Geant4.10 多线程 手动数据合并

本文档介绍了在Geant4中如何在多线程环境下手动合并并输出数据,由于Geant4的运行机制,主线程和工作线程会分别执行RunAction。通过在EndOfRunAction中利用IsMaster()判断是否为主线程,实现主线程的数据导出和文件读写,避免了线程同步问题。同时,使用静态变量在工作线程中累加数据,确保了数据的正确合并。

如题 如何在多线程中手动进行数据合并

缘起

笔者不喜欢ROOT,也不太会用。对于小规模的数据,使用CSV存储查看起来更为方便。但是在Geant4中使用csv存储似乎不支持数据的自动合并。也就是说在面对多线程任务时,输出数据是一个困难。

而且,如果在RunAction或者main()中进行文件读写,会出现多个线程同时读写同一文件的情况,如果没有加文件锁,很容易报错。

问题的关键

笔者发现Geant4的每一个线程都会执行一遍main(){}以及RunAction(){}中的内容,这会给多线程数据手动合并带来困扰。因为难以判断当前是哪一个线程在执行什么,并且在上述地方使用GetThreadID()也并不能正确获取ID。

问题的钥匙

Geant4中,线程分为1个主线程和若干个工作线程。在RunAction中的内容,先由工作线程执行一遍,随即由主线程再执行一遍。因此获取ThreadID的结果总会被主线程的ThreadID=-1说覆盖。

在Geant4.10版本,可以在RunAction中使用 IsMaster() 来判断是否在主线程,因此这也是解决手动数据合并的钥匙。

笔者的做法

在RunAction类中创建静态变量,在RunAction.cc的RunAction::EndOfRunAction(const G4Run* run)使用IsMaster判断是否为主线程,并在工作线程的地方累加静态变量,在Master中进行数据输出和文件读写。

大概逻辑如下:

// in RunAction.hh
class RunAction : public G4UserRunAction
{
   
   
  public:
    RunAction()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值