Segfault与geos并行测试交叉点时
Segfault when testing the intersection with geos in parallel
我正在使用GEOS的C API来管理并行模拟器中的几何体:我需要确保对象位于受约束的区域内。为此,当我的对象迈出一步时,我会检查其先前位置和当前位置之间的line
是否与环境边界相交(environment_manager_->get_border()
,返回const GEOSPreparedGeometry*
)。
该代码与几个OpenMP线程并行运行。在通过开始模拟之前,我初始化了GEOS
initGEOS_r(notice, log_and_exit);
context_handler_ = GEOS_init_r();
所以我对所有线程只有一个处理程序。当使用多个线程运行模拟时,如果我不将GEOSPreparedIntersects_r
封装在关键部分中,则代码会在env_intersect
内部崩溃,并出现segfault。
bool SpaceManager::env_intersect(const GEOSGeometry * line) const
{
bool intersect;
// #pragma omp critical // adding prevents segfault
// {
intersect = GEOSPreparedIntersects_r(
context_handler_, environment_manager_->get_border(), line);
// }
return intersect;
}
有人能指出我做错了什么吗?是否需要对GEOS的初始化进行不同的操作才能使用OpenMP?它是否来自于environment_manager_
是unique_ptr
的事实?这些都没有?
segfault的回溯给出:
Thread 19 "python" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffd63da700 (LWP 4374)]
0x00007ffff78816b2 in tcache_get () from /usr/lib/libc.so.6
(gdb) bt
#0 0x00007ffff78816b2 in tcache_get () at /usr/lib/libc.so.6
#1 0x00007ffff5dbf0a9 in operator new(unsigned long) (sz=sz@entry=32)
at /build/gcc-multilib/src/gcc/libstdc++-v3/libsupc++/new_op.cc:50
#2 0x00007fffc8468273 in geos::geom::LineString::computeEnvelopeInternal() const (this=0x555555f10170) at LineString.cpp:278
#3 0x00007fffc845b95f in geos::geom::Geometry::getEnvelopeInternal() const (this=0x555555f10180) at Geometry.cpp:276
#4 0x00007fffc84612ad in geos::geom::GeometryCollection::computeEnvelopeInternal() const (this=0x555555f15980) at GeometryCollection.cpp:257
#5 0x00007fffc845b95f in geos::geom::Geometry::getEnvelopeInternal() const (this=0x555555f15998) at Geometry.cpp:276
#6 0x00007ffff53cea66 in geos::geom::prep::BasicPreparedGeometry::envelopesIntersect(geos::geom::Geometry const*) const () at /usr/lib/libgeos-3.6.2.so
#7 0x00007ffff53cef82 in geos::geom::prep::PreparedLineString::intersects(geos::geom::Geometry const*) const () at /usr/lib/libgeos-3.6.2.so
#8 0x00007ffff5907380 in GEOSPreparedIntersects_r ()
at /usr/lib/libgeos_c.so.1
#9 0x00007ffff61d7938 in growth::SpaceManager::env_intersect(GEOSGeom_t const*) const (this=0x555555fb3b78, line=0x7fff7c045c20)
[EDIT]为每个OMP线程制作一个环境的const GEOSPreparedGeometry*
副本,并仅访问线程特定的副本,可以在没有critical
部分的情况下成功防止segfault。代码变为:
intersect = GEOSPreparedIntersects_r(
context_handler_, environment_manager_->get_border(omp_id), line);
其中CCD_ 10返回线程特定的CCD_。这意味着问题来自于我以前使用单个指针时对共享数据的并发访问。这看起来很奇怪,因为函数应该是线程安全的。。。
显然线程安全实现还没有准备好(请参阅邮件列表交换)。我通过在每个线程上使用全局环境几何体的副本来解决这个问题(这显然也允许完全并发的测试)。
相关文章:
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- 尽管测试成功,CppUnit测试核心仍被丢弃.为什么
- 数据成员SFINAE的C++17测试:gcc vs clang
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么二进制搜索在我的测试中不起作用
- 从父数组测试用例构造二叉树失败
- 试图对缓存进行跨步测试,但程序并没有结束
- 有什么好的方法可以让系统调用代理允许在单元测试中进行模拟
- OpenGL在启用深度测试时不会丢弃我的碎片
- 为测试目标创建具有不同源文件夹的文件
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- VC++本机单元测试,找不到调试符号
- 换位表导致测试失败(但在游戏中运行良好)
- 用于交叉编译和CMake的预处理器宏的单元测试
- 谷歌测试中的期望值存储在哪里
- 如何在for循环中包含两个索引值的测试条件
- 在cygwin中测试新的boost安装时出现cpp错误
- 使用rdtsc进行基准测试的缺点是什么
- Segfault与geos并行测试交叉点时