代码之家  ›  专栏  ›  技术社区  ›  Silmathoron

与geos并行测试交叉点时的Segfault

  •  3
  • Silmathoron  · 技术社区  · 7 年前

    我正在使用GEOS的C API在并行模拟器中管理几何体:我需要确保对象保持在约束区域内。 为此,当我的对象迈出一步时,我会检查 line environment_manager_->get_border() ,返回一个 const GEOSPreparedGeometry* ).

    initGEOS_r(notice, log_and_exit);
    context_handler_ = GEOS_init_r();
    

    因此,对于所有线程,我只有一个处理程序。 当使用多个线程运行模拟时,代码在内部崩溃 env_intersect 如果我不包装,则使用segfault GEOSPreparedIntersects_r 在关键部分。

    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;
    }
    

    有人能指出我做错了什么吗?使用OpenMP是否需要以不同的方式初始化GEOS?这是因为 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)
    

    [编辑] 制作一个 const GEOSPreparedGeometry公司* 每个OMP线程的环境副本,并且仅访问特定于线程的副本,成功地防止了在没有 critical

    intersect = GEOSPreparedIntersects_r(
            context_handler_, environment_manager_->get_border(omp_id), line);
    

    哪里 environment_manager_->get_border(omp_id) 返回特定于线程的 const GEOSPreparedGeometry公司* . 这意味着,当我以前使用单指针时,问题来自对共享数据的并发访问。这看起来很奇怪,因为函数应该是线程安全的。。。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Silmathoron    7 年前

    显然,线程安全实现尚未就绪(请参阅 mailing list exchange ). 我通过在每个线程上使用全局环境几何体的副本解决了这个问题(这显然也允许完全并发的测试)。