GCD使用中に発生したデッドロックの問題

2076 ワード

デッドロック1、プライマリ・キュー列がプライマリ・スレッドで同期して実行される


次のコードはviewDidLoadに記載されています.
NSLog(@"before: %@", [NSThread currentThread]);
//  ( )
dispatch_queue_t q = dispatch_get_main_queue();

// 5  
for (int index = 0; index < 5; index ++) {

    //  
    dispatch_sync(q, ^{
        NSLog(@"task : %@", [NSThread currentThread]);
    });
}

NSLog(@"after: %@", [NSThread currentThread]);

 :
2016-06-21 12:07:22.921 Thread-Objc[44793:2467944] before: {number = 1, name = main}

  :  
 : ! !

上のデッドロックの書き方は、**プライマリ・キュー列がプライマリ・スレッドでタスク**デッドロックを同期して実行します.

デッドロック2、

NSLog(@"before: %@", [NSThread currentThread]);

dispatch_queue_t q = dispatch_queue_create("q1", DISPATCH_QUEUE_SERIAL);

for (int index = 0; index < 10; index ++) {
    dispatch_async(q, ^{
        NSLog(@"async : %@", [NSThread currentThread]);
        
        dispatch_sync(q, ^{
            NSLog(@"sync :%@", [NSThread currentThread]);
        });
    });
}

NSLog(@"after: %@", [NSThread currentThread]);

 : 
2016-06-23 22:24:46.583 Thread-Objc[14719:2440315] before: {number = 1, name = main}
2016-06-23 22:24:46.583 Thread-Objc[14719:2440315] after: {number = 1, name = main}
2016-06-23 22:24:46.584 Thread-Objc[14719:2440510] async :{number = 2, name = (null)}

上のデッドロックの書き方は、シリアルキューが非同期で実行され、特徴に応じて1つのスレッドが開き、現在のキュースレッドで同期してデッドロックが実行されます.
デッドロックの共通の特徴は、現在のキューの現在のスレッドで同期タスクを実行し、デッドロック!
dispatch_sync関数のAIPには次のような解釈があります.
  • Calls to dispatch_sync() targeting the current queue will result
  • in dead-lock. Use of dispatch_sync() is also subject to the same
  • multi-party dead-lock problems that may result from the use of a mutex.
  • Use of dispatch_async() is preferred.
  • 現在のキューでdispatch_を呼び出すsync()はデッドロックをもたらします.
  • 相互反発ロックにdispatch_を使用するsync()も同様の問題を引き起こす.
  • dispatch_の使用を優先するasync()