2012-08-06 13 views
6

में सुरुचिपूर्ण अपवादण ओपनएमपी कोड को रोकता है जो अपवाद के माध्यम से ओपनएमपी ब्लॉक छोड़ देता है। इसलिए मैं मुख्य थ्रेड में इसे फिर से जोड़ने और बाद के बिंदु पर हैंडलिंग के उद्देश्य से ओपनएमपी ब्लॉक से अपवाद प्राप्त करने का एक अच्छा तरीका ढूंढ रहा हूं।ओपनएमपी

class ThreadException { 
    std::exception_ptr Ptr; 
    std::mutex   Lock; 
public: 
    ThreadException(): Ptr(nullptr) {} 
    ~ThreadException(){ this->Rethrow(); } 
    void Rethrow(){ 
     if(this->Ptr) std::rethrow_exception(this->Ptr); 
    } 
    void CaptureException() { 
     std::unique_lock<std::mutex> guard(this->Lock); 
     this->Ptr = std::current_exception(); 
    } 
}; 
//... 
ThreadException except; 
#pragma omp parallel 
{ 
    try { 
     //some possibly throwing code 
    } 
    catch(...) { except.CaptureException(); } 
} 

हालांकि यह अच्छी तरह से काम करता है, जैसे ही ThreadException वस्तु नष्ट हो जाता है समानांतर अनुभाग से संभव अपवाद rethrowing, इस संरचना अभी भी एक है: अब तक का सबसे अच्छा मैं के साथ आने कर लिया है निम्नलिखित है प्रत्येक खंड के चारों ओर try {}catch(...){} डालने और अपवाद को मैन्युअल रूप से कैप्चर करने के साथ उपयोग करने के लिए थोड़ा अनावश्यक है।

तो मेरा सवाल है: क्या कोई ऐसा करने के लिए एक और अधिक सुरुचिपूर्ण (कम वर्बोज़) तरीका जानता है (और यदि ऐसा है, तो यह कैसा दिखता है)?

+0

आप मामले से कैसे निपटता है जब दो या अधिक धागे अपवाद फेंक (संभवतः अलग-अलग)? –

+0

@HristoIliev: उनमें से एक को अनदेखा करके (क्योंकि मैं फिर भी एक अपवाद नहीं फेंक सकता हूं) और केवल अंतिम को पुनर्स्थापित कर रहा हूं। – Grizzly

+0

एक विनाशक से फेंकना अवैध है (मैंने एक लाइब्रेरी का उपयोग किया है जिसने ऐसा किया है, और यह मुझे तब तक बहुत सी सिरदर्द लाया जब तक मुझे पता नहीं चला कि मेरा आवेदन अपवाद को पकड़ने के बिना क्यों रोक रहा है)। समानांतर खंड के बाद आपको 'छोड़कर। रेथ्रो()' कॉल करना होगा। यदि कोई अपवाद हुआ तो समानांतर अनुभाग के बाद अनुक्रमिक कोड होने पर यह बेहतर होगा। –

उत्तर

8

आप सिंटैक्स को थोड़ा सा साफ करने के लिए कुछ और सी ++ 11 टूल का उपयोग कर सकते हैं। जब एक OpenMP निर्माण अंदर बुला

class ThreadException { 

    // ... 

    template <typename Function, typename... Parameters> 
    void Run(Function f, Parameters... params) 
    { 
     try 
     { 
      f(params...); 
     } 
     catch (...) 
     { 
      CaptureException(); 
     } 
    } 
}; 

फिर तो जैसे एक लैम्ब्डा फ़ंक्शन का उपयोग करें: अपने ThreadException वर्ग को यह variadic सदस्य जोड़ें कार्य

ThreadException e; 

#pragma omp parallel for 
for (int i = 0; i < n; i++) 
{ 
    e.Run([=]{ 
     // code that might throw 
     // ... 
    }); 
} 
e.Rethrow() 
+0

कुछ अजीब कारणों से मैंने अपवाद वर्ग में एक मज़ेदार को पारित करने पर विचार नहीं किया था, इसलिए सुझाव के लिए धन्यवाद। – Grizzly

+1

इसके अलावा, विनाशक से रेथ्रो() को उस कॉल से सावधान रहें - जो दुर्घटनाग्रस्त हो जाएगा और बुरी तरह जला देगा! –

संबंधित मुद्दे