GCDを使って並列処理

Grand Central Dispatch(GCD)を使って並列処理を行うサンプルです。

ポイント
・dispatch_group_tを作成
・dispatch_queue_tの廃棄を行う為にdispatch_group_notifyを仕込む
・UIの変更等はメインスレッドで実行
・共通変数へのアクセスは @synchronized を使ってロックする
・dispatch_group_asyncのブロック内に autoreleasepool を作る

//GCDで複数のジョブを並列で実行してみるサンプル
-(void)gcdTest1
{
    dispatch_queue_t queue_main = dispatch_get_main_queue();
    dispatch_queue_t queue_job = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
  
    NSObject* syncRoot = [[NSObject new]autorelease];//スレッド間の同期用
    __block int counter = 0;
  
    for (int i=0; i<5; i++) {
   
        dispatch_group_async(group, queue_job, ^{
          @autoreleasepool{
              if (i==0)
              {
                  //グループの終了処理を登録しておく
                  //ここではqueue_mainを渡していますが、mainでこのスレッドを待機しているような状況では
                  //デッドロックが起こりますので、その場合はqueue_jobを渡して下さい。
                  dispatch_group_notify(group, queue_main, ^{
                      //dispatch_group_tをリリース
                      dispatch_release(group);
                  
                      //なにか処理を実行(メインスレッドで実行される)
                      NSLog(@"finish group job counter = %d",counter);
                  
                  });
              }
          
              //(ジョブを実行する)
          
              @synchronized(syncRoot){ //共通変数などへのアクセスは@synchronizedを使ってロックする
                  counter += i;
              }
          }
        });
    }
  
    //終了を待機する時は下記のコードで待ちます
    //待機させる時は dispatch_group_notify でリリースさせる必要はなく、
    // ※1でリリースすればOK
    //NSLog(@"waiting...");
    //dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    //dispatch_release(group); //※1
}

上記ではdispatch_group_asyncを複数回発行して並列処理をさせていますが、単純にforを置き換えるような使い方であれば dispatch_apply を使ったら簡単に並列処理が可能です。
ただ、dispatch_applyは処理をロックしてしまいますので、完全に非同期で実行する場合には dispatch_async、dispatch_group_asyncのブロック内でdispatch_applyを実行する事が必要です。

GCDを使って並列処理」への1件のフィードバック

  1. ピンバック: objective-cでマルチスレッド処理(GCD) | 目くじら日記

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です