マルチスレッド - shirai/SwiftLearning GitHub Wiki

マルチスレッド

メインスレッドの役割

目標

  • メインスレッドで実行される重要な処理を説明できる

わかったこと

  • そもそも、スレッドとはプロセス内の、CPU利用権を持つ仮想的な実行の単位である ** スレッドは並列処理を行う際に必要な概念であり、Objective-Cでは並列化を実現する方法として、NSTread、GCD、NSOperationがある
  • 並列処理を行わない場合、処理は全てメインスレッドで実行される
  • ユーザーインターフェースに関わるシステムのメソッド呼び出しは、メインスレッドで実行しなければならない

わからなかったこと

つぎにやること

■「最新iOSプログラミング徹底解説」p90読み込み ■「詳解Objective-C2.0」19章(p480)読み込み ■学習まとめ作成

GCD

目標

  • GCDの記述方法について理解し、任意のブロックを任意の優先度で実行できる
  • GCDを利用して、処理をメインスレッドで実行できる

わかったこと

  • 並列処理を行うアプリケーションを用意に実装するための仕組み
  • GCDはC言語で書かれており、それをObjective-Cのオブジェクトにしたものが、NSOperation
  • 並列で複雑な処理を行いたい場合はNSOperation、簡単な処理を行なう場合はGCDで実装するのが一般的
  • GCDではdispatch queueというキューに処理を行いたいタスクを追加して行くことで、処理を行う
  • タスクはBlocksとして登録する

dispatch queueの種類

同期/非同期

  • dispatch_async:非同期で処理が行われ、実行完了を待たずに制御が進む
  • dispatch_sync:同期的に処理が行われ、タスクの実行が完了するまで制御は止まる

実行数

  • serial dispatch queue:タスクを追加された順に一つずつ実行していく。前の処理が終わり次第、次の処理が始まる。
  • concurrent dispatch queue:複数のタスクを追加された順に実行する。並列で複数の処理を行うため、終わる順番の保証はない。
  • メインディスパッチキュー:メインスレッドで実行するように指定できるキュー。

優先度(concurrent dispatch queueに設定)

  • DISPATCH_QUEUE_PRIORITY_HIGH:優先度高
  • DISPATCH_QUEUE_PRIORITY_DEFAULT:優先度中
  • DISPATCH_QUEUE_PRIORITY_LOW:優先度低
  • DISPATCH_QUEUE_PRIORITY_BACKGROUND:優先度バックグラウンド

キューの取得と生成

  • キューの取得 ** コンカレントキュー dispatch_queue_t dispatch_get_global_queue(優先度, 0); ** メインキュー dispatch_queue_t dispatch_get_main_queue(void);
  • キューの生成 dispatch_queue_t dispatch_queue_create( "逆DNS記法で記述したラベル", DISPATCH_QUEUE_SERIAL or DISPATCH_QUEUE_CONCURRENT);

GCD用例

  • 並列なキューでdispatch_async ** あるタスクは時間もかかり、かつその後の処理でこのタスクの結果を用いない、といったケースに使う for (NSInteger i = 0 ; i < 100; ++i) { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ NSLog(@"%d", i); }); }

NSLog(@"here!!");

  • ログ 2013-05-08 12:49:08.569 GCDSample[12312:3c07] 2 2013-05-08 12:49:08.569 GCDSample[12312:4203] 6 2013-05-08 12:49:08.569 GCDSample[12312:4303] 7 2013-05-08 12:49:08.569 GCDSample[12312:1d03] 0 2013-05-08 12:49:08.569 GCDSample[12312:c07] here!! 2013-05-08 12:49:08.569 GCDSample[12312:4403] 8 2013-05-08 12:49:08.569 GCDSample[12312:3f03] 3 2013-05-08 12:49:08.569 GCDSample[12312:4103] 5 2013-05-08 12:49:08.569 GCDSample[12312:1303] 1 2013-05-08 12:49:08.569 GCDSample[12312:4003] 4 2013-05-08 12:49:08.574 GCDSample[12312:3c07] 9

  • 並列なキューで dispatch_sync ** dispatch_queueで行った内容を後ほど使う必要がある、と言う場合に使う for (NSInteger i = 0 ; i < 100; ++i) { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_sync(queue, ^{ NSLog(@"%d", i); }); }

NSLog(@"here!!");

  • ログ 2013-05-08 13:01:13.691 GCDSample[12490:c07] 0 2013-05-08 13:01:13.692 GCDSample[12490:c07] 1 2013-05-08 13:01:13.692 GCDSample[12490:c07] 2 2013-05-08 13:01:13.692 GCDSample[12490:c07] 3 ~~ 中略 ~~ 2013-05-08 13:01:13.746 GCDSample[12490:c07] 98 2013-05-08 13:01:13.746 GCDSample[12490:c07] 99 2013-05-08 13:01:13.746 GCDSample[12490:c07] here!!

  • 直列なキューで dispatch_async ** 処理内容に一意性が求められる時(ファイルアクセスなど)に使う dispatch_queue_t queue = dispatch_queue_create("jp.tis.ios.sample", DISPATCH_QUEUE_SERIAL); for (NSInteger i = 0 ; i < 100; ++i) { dispatch_sync(queue, ^{ NSLog(@"%d", i); }); }

NSLog(@"here!!");

  • ログ 2013-05-08 13:01:13.691 GCDSample[12490:c07] 0 2013-05-08 13:01:13.692 GCDSample[12490:c07] 1 2013-05-08 13:01:13.692 GCDSample[12490:c07] 2 2013-05-08 13:01:13.692 GCDSample[12490:c07] 3 ~~ 中略 ~~ 2013-05-08 13:01:13.746 GCDSample[12490:c07] 98 2013-05-08 13:01:13.746 GCDSample[12490:c07] 99 2013-05-08 13:01:13.746 GCDSample[12490:c07] here!!

  • 直列なキューで dispatch_sync ** DBなどのように不整合が起きうる箇所で、かつその読み込んだ内容を次で使う、といった場合に使う dispatch_queue_t queue = dispatch_queue_create("jp.mixi.ios.sample", DISPATCH_QUEUE_SERIAL); for (NSInteger i = 0 ; i < 100; ++i) { dispatch_sync(queue, ^{ NSLog(@"%d", i); }); }

NSLog(@"here!!");

  • ログ 2013-05-08 13:01:13.691 GCDSample[12490:c07] 0 2013-05-08 13:01:13.692 GCDSample[12490:c07] 1 2013-05-08 13:01:13.692 GCDSample[12490:c07] 2 2013-05-08 13:01:13.692 GCDSample[12490:c07] 3 ~~ 中略 ~~ 2013-05-08 13:01:13.746 GCDSample[12490:c07] 98 2013-05-08 13:01:13.746 GCDSample[12490:c07] 99 2013-05-08 13:01:13.746 GCDSample[12490:c07] here!!

つぎにやること

■参考サイト読み込み ■実践 ■学習まとめ作成

参考

8.2 Grand Central Dispatch