解决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() 的使用。
创作不易,如果有用,请给个赞再走