2013-03-13 7 views
13

एप्पल डॉक्स में, यह कहते हैं:मैं ग्रैंड सेंट्रल डिस्पैच में डेडलॉक कैसे बना सकता हूं?

महत्वपूर्ण: आप dispatch_sync या एक कार्य है कि एक ही कतार में निष्पादित हो रहा है से dispatch_sync_f फ़ंक्शन को कॉल कभी नहीं करना चाहिए कि आप कार्य करने के लिए पारित करने के लिए की योजना बना रहे हैं। धारावाहिक कतारों के लिए यह विशेष रूप से महत्वपूर्ण है, जो डेडलॉक की गारंटी है, लेकिन भी समवर्ती कतारों से बचना चाहिए।

आप इसे ठीक करने के लिए कोड कैसे लिखते हैं?

+0

आप कोड गतिरोध पैदा करता है इस बात का उदाहरण चाहते हैं? – Vladimir

+0

हाँ कृपया, सीखने के लिए – BlackMouse

+1

एक यथार्थवादी उदाहरण के लिए [यह प्रश्न] (http://stackoverflow.com/questions/10330679/how-to-dispatch-on-main-queue-synchronously-without-a-deadlock) देखें जो आसानी से डेडलॉक कर सकते हैं। – zoul

उत्तर

20

एक जानबूझकर गतिरोध:

dispatch_queue_t queue = dispatch_queue_create("my.label", DISPATCH_QUEUE_SERIAL); 
dispatch_async(queue, ^{ 
    dispatch_sync(queue, ^{ 
     // outer block is waiting for this inner block to complete, 
     // inner block won't start before outer block finishes 
     // => deadlock 
    }); 

    // this will never be reached 
}); 

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

+0

जब डेडलॉक में ... यूआई को उत्तरदायी नहीं होना चाहिए? – BlackMouse

+2

@ user1251004 केवल तभी जब मुख्य कतार अवरुद्ध हो रही है। –

+2

इस उदाहरण में केवल बनाई गई 'कतार' अवरुद्ध है। मुख्य कतार खुशी से चलना जारी है। –

7

सरल कोड है कि बनाता है गतिरोध:

dispatch_queue_t q = dispatch_queue_create("deadlock queue", DISPATCH_QUEUE_SERIAL); 

NSLog(@"1"); 
dispatch_async(q, ^{ 
    NSLog(@"2"); 
    dispatch_sync(q, ^{ 
     NSLog(@"3"); 
    }); 
    NSLog(@"4"); 
}); 
NSLog(@"5"); 

लॉग उत्पादन:

1 
5 
2 

यहाँ आंतरिक ब्लॉक धारावाहिक कतार q पर चलने किया जाना निर्धारित है, लेकिन जब तक वर्तमान ब्लॉक समाप्त हो गया है यह नहीं चल सकता है, जबकि वर्तमान ब्लॉक, बदले में, आंतरिक को समाप्त करने की प्रतीक्षा करता है क्योंकि हम इसे समकालिक रूप से कहते हैं। एक निश्चित कतार पर

4

ब्लॉक करने के लिए सबसे आसान तरीका है वर्तमान कतार पर dispatch_sync के लिए है:

dispatch_sync(dispatch_get_current_queue(), ^{}); 

इस ब्लॉक जब वर्तमान कतार मुख्य कतार उदाहरण के लिए, एक सीरियल कतार है।

0

नवीनतम स्विफ्ट वाक्य रचना में:

let queue = DispatchQueue(label: "label") 
queue.async { 
    queue.sync { 
     // outer block is waiting for this inner block to complete, 
     // inner block won't start before outer block finishes 
     // => deadlock 
    } 
    // this will never be reached 
} 
संबंधित मुद्दे

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