【iPhoneアプリ】他にもまだまだあった「マルチスレッド」について dispatch_group_xxxxxx編
今回は、「マルチスレッド dispatch_group_xxxxx編」についてです。
2部構成の2部目「dispatch_group_xxxxx編」について記載します。
今回は、1ページで収まっております。
dispatch_groupについて
・「dispatch_group」は、いくつかの処理を分散処理させ、結果をまとめて処理を
行いたい時に利用します。
また、「dispatch_group」には、下記のような種類のメソッドを利用できます。
■dispatch_group_create
・ブロックオブジェクトを関連させる事が可能な新しいグループを作成します。
引数 | 説明 |
---|---|
void | 引数指定無し |
■dispatch_group_async
・引数で記述したブロック構文の処理を行う、指定したキューオブジェクトに
グループの関連付けを行う
引数 | 説明 |
---|---|
dispatch_group_t | ディスパチグループオブジェクト |
dispatch_queue_t | ディスパチキューオブジェクト |
dispatch_block_t | タスク処理が書かれたblock構文 |
■dispatch_group_async_f
・引数で指定した関数の処理を行う、指定されたキューオブジェクトにグループ
の関連付けを行う。
引数 | 説明 |
---|---|
dispatch_group_t | ディスパチグループオブジェクト |
dispatch_queue_t | ディスパチキューオブジェクト |
void * | 関数の引数:汎用ポインタ |
dispactch_function | 関数名 |
■dispatch_group_enter
・グループの関連付けを開始する。
(本当はもっと内容は複雑ですが、簡単に理解する為このように記載します。)
引数 | 説明 |
---|---|
dispatch_group_t | ディスパチグループオブジェクト |
■dispatch_group_leave
・グループの関連付けを終了する。
(本当はもっと内容は複雑ですが、簡単に理解する為このように記載します。)
引数 | 説明 |
---|---|
dispatch_group_t | ディスパチグループオブジェクト |
■dispatch_group_notify
・グループ内のブロック処理が完了後、記載されたblock構文の処理を行う
「dispatch_group_wait」は待たなく、次の処理へ進む。
引数 | 説明 |
---|---|
dispatch_group_t | ディスパチグループオブジェクト |
dispatch_queue_t | ディスパチキューオブジェクト |
dispatch_block_t | タスク処理が書かれたblock構文 |
■dispatch_group_notify_f
・グループ内のブロック処理が完了後、記載された関数の処理を行う
「dispatch_group_wait」は待たなく、次の処理へ進む。
引数 | 説明 | |
---|---|---|
dispatch_group_t | ディスパチグループオブジェクト | |
dispatch_queue_t | ディスパチキューオブジェクト | |
void * | 関数の引数:汎用ポインタ | |
dispactch_function | 関数名 |
■dispatch_group_wait
・グループ内の全てのブロック処理を待つ。
引数 | 説明 |
---|---|
dispatch_group_t | ディスパチグループオブジェクト |
timeout | 待ち時間をdispatch_time_t 型(unit64_t型)を使ってナノ秒単位で指定 |
「dispatch_group_async」を用いたグループ処理
・プログラムはこんな感じに書きます。
- (IBAction)thread_Button:(UIButton*)sender { //グローバルキューの作成 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //DispatchGroup の生成 dispatch_group_t group = dispatch_group_create(); /* * グループ処理1 */ for (NSInteger i = 0 ; i < 5; ++i) { dispatch_group_async(group,queue, ^{ NSLog(@"グループ_処理1_実行回数:%d %p", i,[NSThread currentThread]); }); } /* * グループ処理2 */ for (NSInteger i = 0 ; i < 5; ++i) { dispatch_group_async(group,con_queue, ^{ NSLog(@"グループ_処理2_実行回数:%d %p",i,[NSThread currentThread]); }); } //グループのblock処理終了まで待機 dispatch_group_wait(group,DISPATCH_TIME_FOREVER); NSLog(@"同期処理:%p",[NSThread currentThread]); }
・結果はこんな感じです。
labo[23106:3707] グループ_処理1_実行回数:1 0x17595ea0 labo[23106:1803] グループ_処理1_実行回数:0 0x17668590 labo[23106:1803] グループ_処理1_実行回数:2 0x17668590 labo[23106:1803] グループ_処理1_実行回数:3 0x17668590 labo[23106:1803] グループ_処理2_実行回数:0 0x17668590 labo[23106:3707] グループ_処理1_実行回数:4 0x17595ea0 labo[23106:1803] グループ_処理2_実行回数:1 0x17668590 labo[23106:3707] グループ_処理2_実行回数:2 0x17595ea0 labo[23106:1803] グループ_処理2_実行回数:3 0x17668590 labo[23106:3707] グループ_処理2_実行回数:4 0x17595ea0 labo[23106:60b] 同期処理:0x17559a80
この処理では、2つの「dispatch_group_async」が実行された後、「同期処理」が実行されている事が分かります。
「dispatch_group_enter」「dispatch_group_leave」を用いたグループ処理
・プログラムはこんな感じに書きます。
- (IBAction)thread_Button:(UIButton*)sender { //グローバルキューの作成 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //DispatchGroup の生成 dispatch_group_t group = dispatch_group_create(); /* * グループ処理1 */ for (NSInteger i = 0 ; i < 5; ++i) { //グループの関連付けを開始する。 dispatch_group_enter(group); //「dispatch_group_async」ではない非同期処理を実施 dispatch_async(queue, ^{ NSLog(@"グループ_処理1_実行回数:%d %p", i,[NSThread currentThread]); //グループの関連付けを終了する。 dispatch_group_leave(group); //ここはグループ化されてないので待ってない。 NSLog(@"グループ外_処理1_実行回数:%d %p", i,[NSThread currentThread]); }); } //グループのblock処理終了まで待機 dispatch_group_wait(group,DISPATCH_TIME_FOREVER); NSLog(@"同期処理:%p",[NSThread currentThread]); }
・結果はこんな感じです。
labo[23715:1803] グループ_処理1_実行回数:0 0x14625cf0 labo[23715:3707] グループ_処理1_実行回数:1 0x145526c0 labo[23715:1803] グループ外_処理1_実行回数:0 0x14625cf0 labo[23715:1803] グループ_処理1_実行回数:2 0x14625cf0 labo[23715:3707] グループ外_処理1_実行回数:1 0x145526c0 labo[23715:1803] グループ外_処理1_実行回数:2 0x14625cf0 labo[23715:3707] グループ_処理1_実行回数:3 0x145526c0 labo[23715:1803] グループ_処理1_実行回数:4 0x14625cf0 labo[23715:3707] グループ外_処理1_実行回数:3 0x145526c0 labo[23715:60b] 同期処理:0x14518150 labo[23715:1803] グループ外_処理1_実行回数:4 0x14625cf0
この処理では、グループの関連づけされていない「グループ外_処理1」の処理を待たずに「同期処理」が実行されている事が分かります。
・イメージはこんな感じです。
「dispatch_group_notify」を用いたグループ処理
・プログラムはこんな感じに書きます。
- (IBAction)thread_Button:(UIButton*)sender { //グローバルキューの作成 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //DispatchGroup の生成 dispatch_group_t group = dispatch_group_create(); /* * グループ処理1 */ for (NSInteger i = 0 ; i < 5; ++i) { //グループの関連付けを開始する。 dispatch_group_enter(group); //「dispatch_group_async」ではない非同期処理を実施 dispatch_async(queue, ^{ NSLog(@"グループ_処理1_実行回数:%d %p", i,[NSThread currentThread]); //グループの関連付けを終了する。 dispatch_group_leave(group); //ここはグループ化されてないので待ってない。 NSLog(@"グループ外_処理1_実行回数:%d %p", i,[NSThread currentThread]); }); } /* * グループ処理2 */ dispatch_group_async(group,con_queue, ^{ NSLog(@"グループ_処理2 %p",[NSThread currentThread]); }); //グループ処理完了後の処理 dispatch_group_notify(group, queue, ^{ NSLog(@"グループ処理終了後の処理 %p",[NSThread currentThread]); }); //グループのblock処理終了まで待機 dispatch_group_wait(group,DISPATCH_TIME_FOREVER); NSLog(@"同期処理:%p",[NSThread currentThread]); }
・結果はこんな感じです。
labo[23747:3707] グループ_処理1_実行回数:1 0x15595ba0 labo[23747:1803] グループ_処理1_実行回数:0 0x156a8190 labo[23747:1803] グループ_処理1_実行回数:3 0x156a8190 labo[23747:3707] グループ_処理1_実行回数:2 0x15595ba0 labo[23747:1803] グループ_処理1_実行回数:4 0x156a8190 labo[23747:3707] グループ_処理2 0x15595ba0 labo[23747:60b] 同期処理:0x1567ef60 labo[23747:3707] グループ処理終了後の処理 0x15595ba0
この処理では、「同期処理」が実行され、同時に「dispatch_group_notify」が実行されている事が分かります。
・イメージはこんな感じです。