2014-12-07 18 views
1

採取以下代碼:使用的unique_ptr <CCfits :: FITS>在OMP並行for循環導致SEG.FAULT

#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%的賽格。 FAULT和10%OK
  3. 如何解決這個問題?
  4. 我可以解決這個問題嗎?

I.簡單地運行代碼結果爲 90%賽格。 FAULT 10%OK

二,使用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。

==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) 

回答

0

嘛,你使用了大量的不良做法,即使我不知道適合anythings,我可以看到:在

以下使用的valgrind --tool = DRD ./code結果
  • 您正在創建4個執行相同操作的線程:讀取文件,該文件被讀取4次並且是SAME文件。閱讀一次並共享CONST數據會更好嗎?
  • 如果Fits正在跟蹤已經打開的文件(我不知道),可能沒有準備好多線程。

    對不起,我的英語。