2013-04-02 5 views
5

मुझे हार्डवेयर के एक टुकड़े के आसपास इंटरप्रोसेस सिंक्रनाइज़ेशन की आवश्यकता है। चूंकि इस कोड को विंडोज और लिनक्स पर काम करने की आवश्यकता होगी, इसलिए मैं बूस्ट इंटरप्रोसेस म्यूटेक्स के साथ लपेट रहा हूं। म्यूटक्स के त्याग की जांच के लिए सब कुछ मेरी विधि को अच्छी तरह से स्वीकार करता है। ऐसी संभावना है कि यह हो सकता है और इसलिए मुझे इसके लिए तैयार रहना चाहिए।इंटरप्रोसेस म्यूटेक्स को बढ़ावा दें और त्याग के लिए जांच

मैंने अपने परीक्षण में म्यूटेक्स को छोड़ दिया है और, निश्चित रूप से पर्याप्त है, जब मैं mutex को लॉक करने के लिए scoped_lock का उपयोग करता हूं, प्रक्रिया अनिश्चित काल तक अवरुद्ध होती है। मैंने सोचा कि स्कोप्ड_लॉक पर टाइमआउट तंत्र का उपयोग करके इस तरह का तरीका है (क्योंकि समय के लिए गुगलिंग के लिए गुगलिंग खर्च करने के लिए वास्तव में बहुत कुछ नहीं दिखाया जाता है, पोर्टेबिलिटी कारणों से बूस्ट इसके आसपास बहुत कुछ नहीं करता है)।

आगे की हलचल के बिना, यहाँ मैं क्या है:

#include <boost/interprocess/sync/named_recursive_mutex.hpp> 
#include <boost/interprocess/sync/scoped_lock.hpp> 

typedef boost::interprocess::named_recursive_mutex MyMutex; 
typedef boost::interprocess::scoped_lock<MyMutex> ScopedLock; 

MyMutex* pGate = reinterpret_cast<MyMutex*>(new MyMutex(boost::interprocess::open_or_create, "MutexName"); 

{ 
    // ScopedLock lock(*pGate); // this blocks indefinitely 
    boost::posix_time::ptime timeout(boost::posix_time::microsec_clock::local_time() + boost::posix_time::seconds(10)); 
    ScopedLock lock(*pGate, timeout); // a 10 second timeout that returns immediately if the mutex is abandoned ????? 
    if(!lock.owns()) { 
     delete pGate; 
     boost::interprocess::named_recursive_mutex::remove("MutexName"); 
     pGate = reinterpret_cast<MyMutex*>(new MyMutex(boost::interprocess::open_or_create, "MutexName"); 
    } 
} 

, यही कारण है कि कम से कम, विचार है। तीन दिलचस्प अंक:

  • जब मैं टाइमआउट वस्तु नहीं का उपयोग करते हैं , और म्युटेक्स छोड़ दिया जाता है, ScopedLock ctor ब्लॉक अनिश्चित काल के लिए। यह उम्मीद है।
  • जब मैं समय-समय पर का उपयोग करता हूं, और म्यूटेक्स छोड़ दिया जाता है, स्कोप्ड लॉक सीटीआर तुरंत लौटता है और मुझे बताता है कि यह म्यूटेक्स का मालिक नहीं है। ठीक है, शायद यह सामान्य है, लेकिन यह 10 सेकेंड का इंतजार क्यों नहीं कर रहा है, मैं इसे भी बता रहा हूं?
  • जब म्यूटेक्स को छोड़ दिया नहीं गया है, और मैं टाइमआउट का उपयोग करता हूं, स्कोप्ड लॉक सीटीओ अभी भी तुरंत लौटता है, मुझे बता रहा है कि यह लॉक नहीं कर सकता है, या म्यूटेक्स का स्वामित्व ले सकता है और मैं हटाने की गति से गुजरता हूं म्यूटेक्स और इसे रीमेकिंग। यह वही नहीं है जो मैं चाहता हूं।

तो, इन वस्तुओं का उपयोग करने में मुझे क्या याद आ रही है? शायद यह मुझे चेहरे पर देख रहा है, लेकिन मैं इसे नहीं देख सकता और इसलिए मैं मदद मांग रहा हूं।

मुझे यह भी उल्लेख करना चाहिए कि यह हार्डवेयर कैसे काम करता है, अगर प्रक्रिया 10 सेकंड के भीतर म्यूटेक्स के स्वामित्व को प्राप्त नहीं कर पाती है, तो म्यूटेक्स को छोड़ दिया जाता है। वास्तव में, मैं शायद 50 या 60 मिलीसेकंड जितना कम इंतजार कर सकता हूं, लेकिन 10 सेकंड उदारता का एक अच्छा "दौर" संख्या है।

मैं विंडोज 7 पर संकलन कर रहा हूँ दृश्य स्टूडियो का उपयोग कर 2010

धन्यवाद, एंडी

+2

आपके प्रश्न से संबंधित नहीं है, लेकिन आपके उदाहरण में 'reinterpret_cast 'की आवश्यकता नहीं है (सुनिश्चित नहीं है कि वे वहां क्यों हैं)। –

+0

@GaborMarton मुझे लगता है कि मैं निकालने() फ़ंक्शन का सही उपयोग कर रहा हूं। कोड फिर से जांचें। मैं सूचक को हटा रहा हूं, जो मैं सहमत हूं, म्यूटेक्स को नहीं हटाता है, लेकिन फिर मैं कॉल बूस्ट :: इंटरप्रोसेस :: name_recursive_mutex :: हटाएं ("MyMutex")। अगर मैंने इसका गलत इस्तेमाल किया है, तो कृपया मुझे सही करें। धन्यवाद –

+0

हाँ, आप सही हैं, बस मेरी टिप्पणी हटा दी, और मेरा जवाब अपडेट किया। उम्मीद है की वो मदद करदे। –

उत्तर

4

जब मैं टाइमआउट वस्तु का उपयोग नहीं करते, और म्युटेक्स छोड़ दिया जाता है, ScopedLock ctor ब्लॉक अनिश्चित काल के लिए। यह उम्मीद है कि

आपकी समस्या के लिए सबसे अच्छा समाधान होगा अगर बूस्ट मजबूत म्यूटेक्स के लिए समर्थन था। हालांकि बूस्ट वर्तमान में मजबूत म्यूटेक्स का समर्थन नहीं करता है। मजबूत म्यूटेक्स का अनुकरण करने की केवल एक योजना है, क्योंकि केवल लिनक्स पर इसका मूल समर्थन है। इम्यूलेशन अभी भी लाइब्रेरी लेखक, आयन गजटानागा द्वारा नियोजित है। चेक rubust mutexes के संभावित हैकिंग के बारे में इस लिंक को बढ़ावा देने libs में: http://boost.2283326.n4.nabble.com/boost-interprocess-gt-1-45-robust-mutexes-td3416151.html

इस बीच आप एक साझा क्षेत्र में परमाणु चर का उपयोग करने के लिए कोशिश कर सकते हैं। How do I take ownership of an abandoned boost::interprocess::interprocess_mutex?

जब मैं समय समाप्ति का उपयोग करते हैं, और म्युटेक्स छोड़ दिया जाता है, ScopedLock ctor रिटर्न तुरंत और मुझसे कहता है कि यह म्युटेक्स का स्वामी नहीं है:

इसके अलावा इस stackoverflow प्रविष्टि पर एक नज़र । ठीक है, शायद यह सामान्य है, लेकिन यह 10 सेकेंड का इंतजार क्यों नहीं कर रहा है, मैं इसे भी बता रहा हूं?

यह बहुत अजीब है, आपको यह व्यवहार नहीं मिलना चाहिए। हालांकि: टाइम लॉक संभवतः लॉक लॉक के संदर्भ में लागू किया गया है। इस दस्तावेज़ीकरण की जांच करें: http://www.boost.org/doc/libs/1_53_0/doc/html/boost/interprocess/scoped_lock.html#idp57421760-bb इसका मतलब है कि, समय के लॉक के कार्यान्वयन आंतरिक रूप से अपवाद फेंक सकता है और फिर झूठा लौटा सकता है।

inline bool windows_mutex::timed_lock(const boost::posix_time::ptime &abs_time) 
{ 
    sync_handles &handles = 
     windows_intermodule_singleton<sync_handles>::get(); 
    //This can throw 
    winapi_mutex_functions mut(handles.obtain_mutex(this->id_)); 
    return mut.timed_lock(abs_time); 
} 

संभवतः, हैंडल प्राप्त नहीं किया जा सकता है, क्योंकि म्यूटेक्स को त्याग दिया जाता है।

जब म्युटेक्स परित्यक्त नहीं है, और मैं समय समाप्ति का उपयोग करें, ScopedLock ctor अभी भी तुरंत वापस लौट, मुझे बता कि यह लॉक कर सकता है, या म्युटेक्स की, स्वामित्व लेने और मैं की गति के माध्यम से जाना म्यूटेक्स को हटाने और इसे रीमेक करना। यह वही नहीं है जो मैं चाहता हूं।

मुझे इस बारे में निश्चित नहीं है, लेकिन मुझे लगता है कि नामित म्यूटेक्स को साझा स्मृति का उपयोग करके कार्यान्वित किया जाता है। यदि आप लिनक्स का उपयोग कर रहे हैं, तो फ़ाइल/dev/shm/mutexName की जांच करें। लिनक्स में, फ़ाइल डिस्क्रिप्टर तब तक मान्य रहता है जब तक कि बंद न हो, कोई फर्क नहीं पड़ता कि आपने फ़ाइल को स्वयं हटा दिया है या नहीं। को बढ़ावा देने :: इंटरप्रोसेस :: named_recursive_mutex :: हटा दें। बाहर BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING और BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS

+0

उत्तर के रूप में चिह्नित करने में भयानक देरी के लिए खेद है। असल में, बूस्ट में पोर्टेबिलिटी के कारण, हमने समय के लिए इस "समस्या" के साथ रहने का फैसला किया है। –

3

चेक झंडे संकलन। इंटरप्रोसेस म्यूटेक्स को समय-समय पर और टाइमआउट अवधि को परिभाषित करने के लिए दूसरा प्रतीक बल देने के लिए अपने कोड में पहला प्रतीक परिभाषित करें।

मैंने छोड़े गए म्यूटेक्स मुद्दे को हल करने के लिए उन्हें लाइब्रेरी में जोड़ने में मदद की। कई इंटरप्रोसेस संरचनाओं (जैसे message_queue) के कारण इसे जोड़ना आवश्यक था जो कि समय के म्यूटेक्स की बजाय साधारण म्यूटेक्स पर भरोसा करते थे। भविष्य में एक और मजबूत समाधान हो सकता है, लेकिन इस समाधान ने मेरी इंटरप्रोसेस जरूरतों के लिए ठीक काम किया है।

मुझे खेद है कि मैं इस समय आपके कोड के साथ आपकी सहायता नहीं कर सकता; कुछ ठीक से काम नहीं कर रहा है।

1

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

#define TIMEOUT 1000 
#define SAFELOCK(pMutex) \ 
    boost::posix_time::ptime wait_time \ 
     = boost::posix_time::microsec_clock::universal_time() \ 
     + boost::posix_time::milliseconds(TIMEOUT); \ 
    boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(*pMutex, wait_time); \ 
    if(!lock.owns()) { \ 
     pMutex->unlock(); } 

लेकिन यह भी इष्टतम नहीं है, क्योंकि लॉक होने वाला कोड अब अनलॉक हो जाता है। इससे समस्याएं हो सकती हैं। हालांकि आप आसानी से मैक्रो का विस्तार कर सकते हैं। जैसे केवल रन कोड अगर lock.owns() सत्य है।

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