2012-02-27 13 views
6
static pthread_mutex_t gLock; //global 

pthread_mutex_init(&gLock,NULL); //in init 

pthread_mutex_lock(&gLock); 
for(int i=0;i<[message count];i++) 
CFSetAddValue(mSet, [message objectAtIndex:i]); 
pthread_mutex_unlock(&gLock); 

मेरा कोको एप्लिकेशन pthread_mutex_t के साथ मोड का जवाब नहीं दे रहा है।pthread_mutex_t वीएस @ सिंक्रनाइज़ ब्लॉक?

@synchronized(mSet) 
{ 
for(int i=0;i<[message count];i++) 
    CFSetAddValue(mSet, [message objectAtIndex:i]); 
} 

मेरा एप्लिकेशन सिंक्रनाइज़ ब्लॉक के साथ ठीक काम कर रहा है।

क्यों?

उत्तर

8

आप ऑब्जेक्ट लेवल रिकर्सिव लॉक (एक लॉक प्रति उदाहरण, जिसे एक ही थ्रेड से कई बार अधिग्रहित किया जा सकता है) में एक वैश्विक लॉक (सभी उदाहरणों के लिए एक लॉक) की तुलना कर रहे हैं। ये आम तौर पर एक दूसरे से अलग नहीं होते हैं - वे एक दूसरे से बहुत अलग काम करते हैं और रक्षा करते हैं।

अच्छी खबर यह है कि आप pthread_mutex_t का उपयोग रिकर्सिव लॉक के रूप में कर सकते हैं जो @synchronized के समान सुरक्षा प्राप्त करने के लिए प्रत्येक उदाहरण के लिए अद्वितीय है। pthread_mutex_t का उपयोग करके लॉक अधिग्रहण भी बहुत तेज़ हो जाता है।

एक pthread म्युटेक्स का उपयोग कर @synchronized रूप में एक ही प्रभाव को प्राप्त करने के लिए, एक उदाहरण चर के रूप में pthread_mutex_t gLock घोषित, तो -init में एक पुनरावर्ती म्युटेक्स के रूप में यह आरंभ कर देगा। अंत में, -dealloc में म्यूटेक्स को नष्ट करें।

बेशक, उप-और बेस-क्लास को इस लॉक तक पहुंच की आवश्यकता हो सकती है यदि वे ऑब्जेक्ट पदानुक्रम के माध्यम से सही चीज़ करने के लिए @synchronized के अर्थशास्त्र पर भरोसा करते हैं।

@synchronized एक रिकर्सिव पर्थ्रेड म्यूटेक्स (पिछली बार जांच की गई) की तुलना में धीमी गति से धीमी गति से धीमी है।

+1

.h फ़ाइल में \t pthread_mutexattr_t attr; \t pthread_mutex_t mutex; init \t \t pthread_mutexattr_settype (और attr, PTHREAD_MUTEX_RECURSIVE); \t \t pthread_mutex_init (और म्युटेक्स, &attr); dealloc में pthread_mutex_destroy (और म्युटेक्स); मेरी समारोह pthread_mutex_lock में (और म्युटेक्स); \t \t \t \t CFSetRemoveAllValues ​​(mySet); \t \t \t pthread_mutex_unlock (और म्युटेक्स); है यह ठीक है? –

+1

@ParagBafna ए) mutex attr 'static' हो सकता है, और आपके द्वारा बनाए गए प्रत्येक म्यूटेक्स के लिए उपयोग किया जाता है - या गैर स्थैतिक और केवल '-init' b में उपयोग किया जाता है) mutex attr को ivar c नहीं होना चाहिए c) आपको अपना सत्यापन करना चाहिए परिणाम कोड डी) आप कुछ मामलों में 'pthread_mutex_trylock' भी पसंद कर सकते हैं। ई) आपको प्रारंभकर्ताओं का उपयोग करके structs शुरू करना चाहिए। उसके अलावा अच्छा लग रहा है! तेजी से लॉकिंग के लिए तैयार करें =) – justin

+0

परिणाम कोड अधिकतर लॉकिंग और थ्रेडिंग त्रुटियों का पता लगाने के लिए उपयोगी होते हैं। । – justin

0

जस्टिन सही है; हालांकि, एक और विवरण भी है, जो अपवाद हैंडलिंग है। https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html से इस टिप आता है:

एक एहतियाती उपाय के रूप में, @synchronized ब्लॉक परोक्ष संरक्षित कोड के लिए अपवाद संचालक कहते हैं। यह हैंडलर स्वचालित रूप से उस घटना में म्यूटेक्स को रिलीज़ करता है जब एक अपवाद फेंक दिया जाता है। इसका मतलब है कि @ सिंक्रनाइज़ निर्देश का उपयोग करने के लिए, आपको अपने कोड में उद्देश्य-सी अपवाद हैंडलिंग भी सक्षम करना होगा। यदि आप निहित अपवाद हैंडलर के कारण अतिरिक्त ओवरहेड नहीं चाहते हैं, तो आपको लॉक कक्षाओं का उपयोग करने पर विचार करना चाहिए।

यदि [message count] अपवाद उठा सकते हैं जो आपके अनलॉक कोड पर कूद सकते हैं और आपको वेज कर सकते हैं।

+0

... यदि आप ठीक हो सकते हैं। अधिकांश कोको अपवाद पुनर्प्राप्त करने योग्य नहीं होते हैं (कम से कम, यदि आप इसके बाद अनुमानित निष्पादन चाहते हैं)। पुनर्प्राप्ति योग्य अपवाद के लिए सामान्य मामला सी ++ (अनुमानित वसूली) होगा। – justin