解决Geant4 11版本多线程写入txt文件出现数据错误、乱码问题

解决Geant4 11版本多线程写入txt文件出现数据错误、乱码问题

Geant4多线程写入txt文件

需要记录快中子在塑闪中的一些信息,统计所产生不同的次级质子能量、时间、位置信息,并在eventaction中写入txt文件

信息统计完后使用root处理txt文件数据,却出现了令人头疼的报错。

**@ubuntu:~/work/S_temp/1$ root -l spectrum.cpp 
root [0] 
Processing spectrum.cpp...

 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x00007fd51554cc3a in __GI___wait4 (pid=10176, stat_loc=stat_loc
entry=0x7ffc0db0e9e8, options=options
entry=0, usage=usage
entry=0x0) at ../sysdeps/unix/sysv/linux/wait4.c:27
#1  0x00007fd51554cbfb in __GI___waitpid (pid=<optimized out>, stat_loc=stat_loc
entry=0x7ffc0db0e9e8, options=options
entry=0) at waitpid.c:38
#2  0x00007fd5154bbf67 in do_system (line=<optimized out>) at ../sysdeps/posix/system.c:172
#3  0x00007fd515b6b0ee in TUnixSystem::StackTrace() () from /home/**/work/root/lib/libCore.so.6.24
#4  0x00007fd515b67f65 in TUnixSystem::DispatchSignals(ESignals) () from /home/**/work/root/lib/libCore.so.6.24
#5  <signal handler called>
#6  0x00007fd50f5f3ba4 in ?? ()
#7  0x0000000000000000 in ?? ()
===========================================================


The lines below might hint at the cause of the crash.
You may get help by asking at the ROOT forum https://root.cern.ch/forum
Only if you are really convinced it is a bug in ROOT then please submit a
report at https://root.cern.ch/bugs Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#6  0x00007fd50f5f3ba4 in ?? ()
#7  0x0000000000000000 in ?? ()
===========================================================


Root > 


检查问题

不清楚错误的来源,尝试检查内存有没有溢出,版本不兼容等问题。。。

最后,通过cout不同参数值,终于找到了问题的原因,我写入的txt文件原本每一行的第一列都是eventID,结果在其中某些行却发现该值不是整数,并且该值还与周围其他的值大小相等,造成数据错误、乱码。

初步推断是多线程写入txt文件的问题。

之后,改为单线程

/run/numberOfThreads 1

就可以能成功运行,不再报错。

锁定txt文件

参考csdn上关于读取文件时锁定txt文件的描述:Geant4 学习笔记(一):实现multi-thread多线程https://blog.youkuaiyun.com/weixin_52417815/article/details/112062070

无论是文件的读取还是写入,在使用多线程、分布式、并行计算时,必须考虑锁定机制

eventaction.cc 文件加入lock

由于我需要在eventaction中写入文件,因此在eventaction.cc头文件中加入

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

在 EventAction::EndOfEventAction 中加入

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventAction::EndOfEventAction(const G4Event *aEvent) // (const G4Event* event)
{
  if (aEvent->GetEventID() % 100000 == 0)
  {
    G4cout << " Event => " << aEvent->GetEventID() << endl;
  }
  //  ----------- && lock && lock -----------
  G4AutoLock lock(&detectiontex);

  ofstream output1;
  output1.open("./OutPut/data.txt", ofstream::app);

  if (crash_N != 0 && aEvent->GetEventID() > 0)
  {
    output1 << aEvent->GetEventID() << " ";
    output1 << crash_N << " ";
    for (std::size_t i = 0; i < D1.size(); i++)
    {
      output1 << D1[i] << " ";
    }
    output1 << endl;
  }
  // 依次输出:
  // eveneID,中子所有的碰撞次数,产生的粒子类型,粒子的动能,粒子的位置

  output1.close();
  lock.unlock();
}

问题解决

重点是 G4AutoLock lock(&detectiontex) 以及 lock.unlock() 的使用。

创作不易,如果有用,请给个赞再走

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值