2016-09-08 17 views
14

वहाँ एक सी ++ std::lock() जंग में सुविधा की तरह इस तरह कोड में deadlocking को रोकने के लिए है:क्या डेडलॉकिंग को रोकने के दौरान जंग में एकाधिक म्यूटेक्स लॉक करने की सुविधा है?

type Type0 = Arc<Mutex<u8>>; 
type Type1 = Arc<Mutex<u16>>; 

fn foo(a: Type0, b: Type1) { 
    let a_guard = a.lock().unwrap(); 
    let b_guard = b.lock().unwrap(); 
} 

fn bar(a: Type0, b: Type1) { 
    let b_guard = b.lock().unwrap(); 
    let a_guard = a.lock().unwrap(); 
} 

तो foo वहाँ गतिरोध का एक मौका है धागा 0 और bar से पुकारा जाता है धागा -1 द्वारा। क्या कुछ ऐसा है, उम्मीद है कि अलग-अलग है क्योंकि मेरे पास 2 से अधिक हो सकते हैं, इस के साथ मेरी मदद करने के लिए या क्या मैं लॉकिंग के आदेश की शुद्धता की पुष्टि कर रहा हूं?

the documentation for std::lock से:

एक गतिरोध परिहार एल्गोरिथ्म का उपयोग कर गतिरोध से बचने के लिए दिए गए Lockable वस्तुओं lock1, lock2, ..., lockn लॉक करता है।

+1

मान्य रूप से मुझे नहीं पता कि 'std :: lock' कैसे काम करता है, लेकिन (जब तक आप डेटा को एक साथ लंपाने और इसे लॉक/अनलॉक करने में एमएमस्टिक के उत्तर का पालन नहीं करते) मैं नहीं देखता कि आप कभी * गारंटी * कैसे कर सकते हैं * कोई deadlocks नहीं। निश्चित रूप से, आप उन्हें सही क्रम में करने के लिए एक मैक्रो लिख सकते हैं - लेकिन फिर आपने * जांच की समस्या को अभी बदल दिया है कि आप हमेशा उन्हें सही क्रम में लॉक करते हैं * की जांच करने की मुश्किल-आसान समस्या में * आप हमेशा जांचते हैं मैक्रो का उपयोग करें और कभी भी कॉल करें .lock() सीधे *। सही? – trentcl

+1

[दिलचस्प, संबंधित, लेकिन (मेरे लिए) 'std :: lock' की पूरी तरह से संतोषजनक चर्चा नहीं है] (http: // stackoverflow।कॉम/प्रश्न/18520 9 83/आईएस-स्टडलॉक-बीमार परिभाषित-अनुपूरक-या-बेकार # 18521108) – trentcl

उत्तर

1

नहीं, जंग नहीं है (या अभी तक नहीं है) एक समारोह बराबर करने के लिए है सी ++ के std::lock

इस तथ्य के आधार पर कि यह std::sync documentation में प्रतीत नहीं होता है और गूगलिंग कुछ भी उपयोगी नहीं लाता है, मुझे इस दावे में बहुत भरोसा है।

क्यों नहीं? खैर, अगर मैं थोड़ी सी संपादकीयता कर सकता हूं, std::lock यह बहुत अच्छा विचार नहीं है - डेडलॉक टावर नॉनट्रिविअल है और प्रत्येक एल्गोरिदम में व्यावहारिक कोने के मामले होंगे जिसके परिणामस्वरूप खराब प्रदर्शन या यहां तक ​​कि आजीविका भी होगी। कोई भी आकार-फिट नहीं है-सभी डेडलॉक टावरेंस एल्गोरिदम।

(आप Vec::sort जैसे अन्य कार्यों के लिए एक ही तर्क कर सकते हैं, लेकिन मुझे लगता है कि कई अनुप्रयोगों में "सॉर्टिंग" की आवश्यकता है जहां प्रदर्शन महत्वपूर्ण नहीं है, और किसी भी उचित प्रकार के एल्गोरिदम के लिए पर्याप्त प्रदर्शन किया जाएगा> आवेदनों की 75%। डेडलॉक परिहार, ज्यादातर आवश्यक केवल जब आप पहले से ही कोड में अच्छा प्रदर्शन करने की जरूरत है कि लिख रहे है।)

इसके अलावा मानक पुस्तकालय में एक गतिरोध-परहेज lock समारोह डाल पता चलता है कि यह एक अच्छा डिफ़ॉल्ट पसंद है , और इसके कार्यान्वयन के संबंध में इसके उपयोग को प्रोत्साहित करता है। हकीकत में, अधिकतर अनुप्रयोग शायद एक सरल (और कम सामान्य उद्देश्य) एल्गोरिदम के साथ बेहतर प्रदर्शन करेंगे।

वैसे भी, इस समस्या को हल करने के लिए आपको कुछ भी "बैकिंग ऑफ" एल्गोरिदम लिखने से रोकता है; यह सिर्फ मानक पुस्तकालय का हिस्सा नहीं है।

2

यह आसानी से सुलझाया जाता है यदि Mutex निहित मानों के साथ एक टुपल है, ताकि ट्यूपल लॉकिंग दोनों मूल्यों को एक साथ लॉक कर दे।

let tuple_mutex = Arc::new(Mutex::new((A, B))); 
+5

उत्कृष्ट बिंदु, लेकिन हो सकता है कि स्वतंत्र मूल्यों की लचीलापन बनाए रखना चाहें। –

+0

हम देख सकते हैं कि टुपल सिर्फ एक ही प्रकार है - इसलिए मूल रूप से एक प्रकार का म्यूटक्सिंग होता है। मैं जो खोज रहा हूं वह अलग म्यूटक्स का समाधान है। ग्रैन्युलरिटी के लिए आप शायद _always_ को एक सिंगल टुपल/टाइप में नहीं लेना चाहते हैं - तो आप ऐसे मामलों का त्याग कर रहे हैं जहां वे मेरे कोड में एक-दूसरे से स्वतंत्र काम कर सकते हैं। यह वास्तव में एक अंतर है 'आर्क <म्यूटक्स' पूरे 'स्ट्रक्चर' बनाम 'आर्क <म्यूटक्सिंग व्यक्तिगत फ़ील्ड'। उत्तरार्द्ध बहुत बेहतर नियंत्रण देता है और मेरा प्रश्न इसके बारे में था - क्या सी ++ के 'std :: lock' के समान सुविधा है। – ustulation

+0

क्या यह वास्तव में हमें म्यूटक्स्ट को एक साथ लॉक करने की इजाजत देता है, या क्या वे वास्तव में दूसरे के बाद एक लॉक हो जाते हैं? यदि हां, तो म्यूटटेक्स्ट में किस क्रम में अनलॉक किया गया है? –

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