try_lock* से, मेरा मतलब try_lock(), try_lock_for(), और try_lock_until() से है। cppreference के अनुसार, सभी तीन विधियां सहज रूप से विफल हो सकती हैं। try_lock_for() के विवरण से उद्धृत किया गया है

try_lock() के रूप में, इस फ़ंक्शन को सहजता से विफल होने की अनुमति है और वापसी false भले ही म्यूटेक्स को किसी अन्य धागे से लॉक न किया गया हो timeout_duration के दौरान कुछ बिंदु।

मुझे पता है कि std::condition_variable और इसके पीछे तर्क के साथ अजीबोगरीब हो सकता है। लेकिन, म्यूटेक्स के साथ मामला क्या है?

12
Lingxi 25 नवम्बर 2015, 06:27

2 जवाब

सबसे बढ़िया उत्तर

इसके अनुसार: http://www.open-std.org/jtc1 /sc22/wg21/docs/papers/2010/n3209.htm

दूसरी ओर, इस बात के लिए मजबूत कारण हैं कि कार्यक्रमों को सहज प्रयत्नशील () विफलताओं को सहन करने के लिए लिखा जाए:

  1. जैसा कि बोएहम में बताया गया है, Adve, "C ++ कॉनसेरी मेमोरी मॉडल की नींव", PLDI 08, बिना डेटा के रेस-फ्री प्रोग्राम्स के लिए अनुक्रमिक स्थिरता को लागू करने के लिए बिना किसी अड़चन के try_lock () विफलताओं के लिए try_lock () पर लॉक () ऑपरेशन के लिए काफी मजबूत ऑर्डर देने की आवश्यकता होती है ) -संपन्न म्यूटेक्स प्रकार। कुछ आर्किटेक्चर पर जो अनियंत्रित म्यूटेक्स अधिग्रहण की लागत को काफी बढ़ाता है। यह लागत बहुत ही तेज़ होती है, जो कि स्प्राईस try_lock () विफलताओं पर रोक लगाने से कोई लाभ प्राप्त नहीं करता है।
  2. यह उपयोगकर्ता-लिखित try_lock () को विफल करने की अनुमति देता है, उदाहरण के लिए, म्यूटेक्स डेटा संरचना की सुरक्षा के लिए निम्न-स्तरीय लॉक को प्राप्त करने के लिए कार्यान्वयन विफल हो जाता है। या यह इस तरह के ऑपरेशन को तुल्यता की तुलना में सीधे लिखा जा सकता है।
  3. यह सुनिश्चित करता है कि क्लाइंट कोड सही रहता है, उदाहरण के लिए, एक डिबगिंग थ्रेड पेश किया जाता है जो कभी-कभी लॉक को प्राप्त करता है ताकि डेटा संरचना से लगातार मूल्यों को जांचा या परखा जा सके। कोई भी कोड जो try_lock () विफलता से जानकारी प्राप्त करता है, वह एक और धागे की शुरूआत के साथ टूट जाएगा जो विशुद्ध रूप से लॉक हो जाता है और डेटा संरचना को पढ़ता है।
16
Anders 25 नवम्बर 2015, 04:35

C ++ 14 अध्याय "30.4.1.2 म्यूटेक्स प्रकार" से

अनुच्छेद 16:

एक कार्यान्वयन लॉक प्राप्त करने में विफल हो सकता है, भले ही वह किसी अन्य धागे द्वारा आयोजित न हो। [नोट: यह सहज विफलता सामान्य रूप से असामान्य है, लेकिन एक सरल तुलना और विनिमय (क्लाज 29) के आधार पर दिलचस्प कार्यान्वयन की अनुमति देता है। -नोट नोट] एक कार्यान्वयन सुनिश्चित करना चाहिए कि try_lock() लगातार म्यूटेक्स अधिग्रहण के अभाव में false वापस नहीं आता है।

और पैराग्राफ 19:

थोड़ा तो असफलता के बाद की स्थिति के बारे में भी जाना जाता है, यहाँ तक कि सहज विफलताओं के अभाव में भी

और उत्तर में

मुझे पता है कि spurious वेकअप std :: condition_variable और इसके पीछे तर्क के साथ हो सकता है। लेकिन, म्यूटेक्स के साथ मामला क्या है?

std::timed_mutex कभी-कभी OS में कोई प्रत्यक्ष समर्थन नहीं होने पर std::condition_varible का उपयोग करके लागू किया जाता है। GNU libstdc ++ की तरह:

#if _GTHREAD_USE_MUTEX_TIMEDLOCK

...

#else // !_GTHREAD_USE_MUTEX_TIMEDLOCK

  class timed_mutex
  {
    mutex       _M_mut;
    condition_variable  _M_cv;
    bool        _M_locked = false;

  public:

    template<typename _Rep, typename _Period>
      bool
      try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
      {
        unique_lock<mutex> __lk(_M_mut);
        if (!_M_cv.wait_for(__lk, __rtime, [&]{ return !_M_locked; }))
          return false;
        _M_locked = true;
        return true;
      }

    template<typename _Clock, typename _Duration>
      bool
      try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
      {
        unique_lock<mutex> __lk(_M_mut);
        if (!_M_cv.wait_until(__lk, __atime, [&]{ return !_M_locked; }))
          return false;
        _M_locked = true;
        return true;
      }
  };

#endif
6
Victor Dyachenko 24 मई 2017, 11:04