在omp parallel for循环中使用unique_ptr <ccfits :: fits>会导致SEG.FAULT </ccfits :: fits>

时间:2014-12-07 16:18:20

标签: c++ parallel-processing openmp

请使用以下代码:

#include <omp.h>
#include <CCfits/CCfits>
#include <sys/stat.h>

int main ()
{
  std::string file ( "somefits.fits" );
  std::cout << file  << std::endl;

  // check if file exists
  struct stat bf;
  if ( stat(file.c_str(),&bf ) ) 
  { 
    std::cerr << "Error: the file: " << file << " does not exist " << std::endl;
    exit(-1);
  }

  #pragma omp parallel for schedule (dynamic)
  for ( uint i = 0; i<4; ++i )
  {
    std::unique_ptr<CCfits::FITS> fp (new CCfits::FITS (file, CCfits::Read));
    // do something
  }
  return 0;
}

第一部分注意文件是否存在。然后我想在for循环中使用CCfits :: FITS文件(或不同的文件),它必须是并行的。 在没有并行化线的情况下运行代码非常有效。

我以不同的方式运行代码,请看下面。

  1. 为什么并行化在这个简单的例子中失败了?
  2. 为什么有90%的SEG。 FAULT和10%OK
  3. 如何解决这个问题?
  4. 我能解决这个问题吗?
  5. 予。只需运行代码就可以了 90%SEG。故障 10%确定

    II。使用valgrind运行代码--leak-check = full ./code导致

    ==6654==    by 0x4EC1C11: CCfits::HDUCreator::Make(int, bool, std::vector<std::string, std::allocator<std::string> > const&) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
    ==6654==    by 0x4EB490F: CCfits::FITS::readExtensions(bool) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
    ==6654==    by 0x4EB4FA3: CCfits::FITS::FITS(std::string const&, CCfits::RWmode, bool, std::vector<std::string, std::allocator<std::string> > const&) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
    ==6654==    by 0x4013C4: main._omp_fn.0 (ccfits_omp.cpp:21)
    ==6654==    by 0x540C349: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
    ==6654==    by 0x4C30E7B: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
    ==6654== Other segment start (thread 2)
    ==6654==    at 0x4C34544: pthread_mutex_unlock (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
    ==6654==    by 0x5C09DA1: fits_store_Fptr (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
    ==6654==    by 0x5C15042: ffopen (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
    ==6654==    by 0x4EB2997: CCfits::FITS::open(CCfits::RWmode) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
    ==6654==    by 0x4EB4F84: CCfits::FITS::FITS(std::string const&, CCfits::RWmode, bool, std::vector<std::string, std::allocator<std::string> > const&) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
    ==6654==    by 0x4013C4: main._omp_fn.0 (ccfits_omp.cpp:21)
    ==6654==    by 0x540C349: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
    ==6654==    by 0x4C30E7B: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
    ==6654==    by 0x62B5181: start_thread (pthread_create.c:312)
    ==6654==    by 0x5923EFC: clone (clone.S:111)
    ==6654== Other segment end (thread 2)
    ==6654==    at 0x4C338E3: pthread_mutex_lock (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
    ==6654==    by 0x5C09E1E: fits_clear_Fptr (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
    ==6654==    by 0x5C1066E: ffclos (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
    ==6654==    by 0x4EB2DE5: CCfits::FITS::close() (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
    ==6654==    by 0x4EB32FD: CCfits::FITS::destroy() (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
    ==6654==    by 0x4017E7: std::default_delete<CCfits::FITS>::operator()(CCfits::FITS*) const (unique_ptr.h:67)
    ==6654==    by 0x401680: std::unique_ptr<CCfits::FITS, std::default_delete<CCfits::FITS> >::~unique_ptr() (unique_ptr.h:184)
    ==6654==    by 0x4013EB: main._omp_fn.0 (ccfits_omp.cpp:21)
    ==6654==    by 0x540C349: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
    ==6654==    by 0x4C30E7B: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
    ==6654==    by 0x62B5181: start_thread (pthread_create.c:312)
    ==6654==    by 0x5923EFC: clone (clone.S:111)
    ==6654== 
    ==6654== 
    ==6654== For counts of detected and suppressed errors, rerun with: -v
    ==6654== ERROR SUMMARY: 53 errors from 19 contexts (suppressed: 495 from 333)
    

    III。使用valgrind --tool = drd ./code会产生以下结果:

    ==6654==    by 0x4EC1C11: CCfits::HDUCreator::Make(int, bool, std::vector<std::string, std::allocator<std::string> > const&) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
    ==6654==    by 0x4EB490F: CCfits::FITS::readExtensions(bool) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
    ==6654==    by 0x4EB4FA3: CCfits::FITS::FITS(std::string const&, CCfits::RWmode, bool, std::vector<std::string, std::allocator<std::string> > const&) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
    ==6654==    by 0x4013C4: main._omp_fn.0 (ccfits_omp.cpp:21)
    ==6654==    by 0x540C349: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
    ==6654==    by 0x4C30E7B: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
    ==6654== Other segment start (thread 2)
    ==6654==    at 0x4C34544: pthread_mutex_unlock (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
    ==6654==    by 0x5C09DA1: fits_store_Fptr (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
    ==6654==    by 0x5C15042: ffopen (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
    ==6654==    by 0x4EB2997: CCfits::FITS::open(CCfits::RWmode) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
    ==6654==    by 0x4EB4F84: CCfits::FITS::FITS(std::string const&, CCfits::RWmode, bool, std::vector<std::string, std::allocator<std::string> > const&) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
    ==6654==    by 0x4013C4: main._omp_fn.0 (ccfits_omp.cpp:21)
    ==6654==    by 0x540C349: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
    ==6654==    by 0x4C30E7B: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
    ==6654==    by 0x62B5181: start_thread (pthread_create.c:312)
    ==6654==    by 0x5923EFC: clone (clone.S:111)
    ==6654== Other segment end (thread 2)
    ==6654==    at 0x4C338E3: pthread_mutex_lock (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
    ==6654==    by 0x5C09E1E: fits_clear_Fptr (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
    ==6654==    by 0x5C1066E: ffclos (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
    ==6654==    by 0x4EB2DE5: CCfits::FITS::close() (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
    ==6654==    by 0x4EB32FD: CCfits::FITS::destroy() (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
    ==6654==    by 0x4017E7: std::default_delete<CCfits::FITS>::operator()(CCfits::FITS*) const (unique_ptr.h:67)
    ==6654==    by 0x401680: std::unique_ptr<CCfits::FITS, std::default_delete<CCfits::FITS> >::~unique_ptr() (unique_ptr.h:184)
    ==6654==    by 0x4013EB: main._omp_fn.0 (ccfits_omp.cpp:21)
    ==6654==    by 0x540C349: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
    ==6654==    by 0x4C30E7B: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
    ==6654==    by 0x62B5181: start_thread (pthread_create.c:312)
    ==6654==    by 0x5923EFC: clone (clone.S:111)
    ==6654== 
    ==6654== 
    ==6654== For counts of detected and suppressed errors, rerun with: -v
    ==6654== ERROR SUMMARY: 53 errors from 19 contexts (suppressed: 495 from 333)
    

1 个答案:

答案 0 :(得分:0)

嗯,你使用了很多不好的做法,即使我不了解Fits,我也能看到:

  • 您正在创建4个执行相同操作的线程:读取文件,读取文件4次,并且是SAME文件。读一次并分享CONST数据不是更好吗?
  • 如果Fits跟踪已经打开的文件(我不知道),则可能没有为多线程做好准备。

    抱歉我的英文。