Objective-C の atomicity について iphone_dev_jp 東京勉強会で発表しました
PROGRAM
table.testcase th
{
white-space: nowrap;
}
table.testcase td
{
white-space: nowrap;
}
Objective-C の atomicity について発表しました
初めて iPhone アプリを作成し始めたときに誰もが必ず目にする "nonatomic" というキーワード。
その意味が今になってようやく理解できたので、それについて 2013/5/25 日に 株式会社 VOYAGE GROUP で開催された "第4回 iphone_dev_jp 東京 iPhone/Mac 勉強会" で発表してきました。
今回発表したお話はこんな感じでした。
- nonatomic ってなんだろう
- なぜ今頃 atomic の話題なのか
- @property (atomic)って何をしてくれるの?
- 値が壊れる?
- スレッドセーフを考慮する
誰もが iOS プログラミングを創めた瞬間から目にするお馴染みの nonatomic キーワードについての効能から、値が壊れるってどういうことなのか、スレッドセーフを目指す上での要所など。
マルチスレッドを意識したときのプログラミングの考え方について、基本から追って調べていたときのお話です。
そんな発表をさせて頂いてきた勉強会。
ワクワクしながら渋谷の会場を訪れると、まだ数える程だけお会いしたことのある受付の方が「あ、こんにちは!」と声をかけて下さいました。プログラマー同士はちょっと顔見知り程度では敢えて控えめにしがちな気がする中で、嬉しい心配りでした。
もちろんプログラマー同士も懇親会という場となれば、知らない者同士であっても互いにキラキラお話しし出します。
そして、深津さんのさりげなく並々ならない存在感に感動しつつ、ここぽんさんって雰囲気がどこか深津さんに似ているような、と思いつつ。
ところで、今回のような iphone_dev_jp の懇親会のスタイルっていいですね。
同じ会場なのでそのまま(勉強会)の雰囲気が持続するし、懇親会に入るときに椅子だけ片付けることで位置が固定されなくなるのも、ふらりとどこかにお邪魔したりお邪魔されたり、知らない大勢が集まる懇親会づくりにぴったりです。
技術者同士の熱い想いが聞ける、聞こえてくる、そんな懇親会も必見でした。
そんな勉強会も終わった翌日、のんびりと昨日の整理をしてたら、なんと神谷さんからお祝いのツイートを頂きました。
@easystylegk おー、iphone_dev_jp 第四回で発表したんですね!やるー!
— かみやんさん (@kamiyan) 2013年5月26日
あれは iphone_dev_jp 勉強会の第 1 回目、もともと iOS アプリ開発を始めて間もない頃に神谷さんのブログ にすっかり魅了されてしまい、彼が(第 1 回目の)勉強会に参加すると聞き、自分も初めて勉強会というものに参加しようと思ったのでした。
そもそもそのとき初めて世の中に勉強会というものがあることを知り、参加の動機も 9 割がた、彼の発表を聞くことと、一言だけでもご挨拶に、といった具合です。
そこから気づけばずいぶん自分の景色も広がりはじめて。そんな世界へ導いてくれた神谷さんから祝福のツイートを頂けるなんて、今回でいちばん嬉しい思いがけない贈り物でした。
こんなつながりも、勉強会ならではの醍醐味ですね。
発表内容の補足
さて、今回の発表に込め損なった事柄について、補足として記しておこうと思います。
主催者 岸川さんのご指摘通り、今回の発表の趣旨としては「ブロック万歳」なのではなくて、スレッドセーフを考えたときに、こんなところに気を配らないといけないだとか、こんな風に保護するだとか、そんな紹介のための発表でした。
自分は調べて初めて気が付きましたけど、nonatomic とかスレッドセーフとか、その辺りで何気なく目にする割には、実はけっこう深刻で深いお話だったんですね。
スレッドセーフの実現方法について
複数スレッドを扱おうとした場合におすすめなのは断然、スレッドをひとつに統一する方法と、Immutable によるクラス実装の方法です。
Immutable を使えば、実装内部でロックが不要になって、処理効率の大幅向上と併せて、実装自体のプログラムの見通しがとても良くなります。いざ、複数スレッドで使いたいと思ったときにも、そのまま直ぐに実用に耐えるところも嬉しいです。
スレッドを統一する方法も同様に、処理効率が大幅に向上しながらプログラムまで把握しやすくなって良いことづくめです。
逆に、複数スレッドを自由に飛び回って、ブロックで整合性を保つ方法は、余程の正当な理由がない限りはおすすめしません。
単に「ループ中も別のことをしないといけないから」という理由だけで、今の処理スレッドとは別のスレッドで実行するなんてしていると、処理速度が大きく犠牲になるばかりか、些細なタイミングでデッドロックしてしまったり、問題が起きた処理がどのスレッドでいつ呼ばれたかとかが把握できなくなって破綻します。
というか、自分のプログラムはそうやって破綻しました。
プリミティブ型の破壊について
プリミティブ型も壊れると書きましたが、int 型みたいな 1 ステップで書き込めるものは nonatomic でも壊れません。
そしてそれを Objective-C は知っているのか、そういう壊れないデータ型なら atomic 指定をしても nonatomic と同じ速度で実行されるので、内部でしっかり不要なロックは省いてくれる様子でした。
つまり atomic を想定しているクラスなら、想定通り、壊れない型のプロパティでも迷わずしっかり atomic 指定しておけるということですね。
ロックの特徴と処理速度について
@synchronized
大雑把ながら調べた感じ、@synchronized を使ったロックが圧倒的に遅いです。
ただ Objective-C 構文の一環になっているため、中括弧でスコープを示したり、スコープ内からいきなり return で抜けてもしっかりアンロックが行われるなど、プログラミングのしやすさ、そして読みやすさの面では圧倒的に有利です。
NSRecursiveLock
比べてずいぶん処理が軽くなるのが NSRecursiveLock によるロックです。
例外が発生したときや途中で抜けるときのアンロック忘れが起こらないように気を付ける必要があるものの、Objective-C クラスなので扱いやすいと思います。
ちなみに NSRecursiveLock は再起ロックなので、同じスレッド内であれば、同じキーで別のところでロックしてても実行できます。もちろん同一スレッドであれば同時実行されることがないので矛盾は起こりません。
NSLock
同じキーならスレッドが同じでもロックしていい場合は、通常ロックの NSLock が使えます。
再起ロックではロックすべき場面かどうかの判定が入る分、通常ロックの方が僅かに速いのですが、ロックの中でいろいろなメソッドを呼び進めているうちに簡単にデッドロックしたりするので注意です。
pthread_mutex
ちなみに pthread_mutex でも NSRecursiveLock や NSLock とまったく同じロックができます。
こちらは C 言語スタイルの関数なので慣れが少し必要ですけど、動作速度は NSLock などより速いので、速度を気にするならこちらが良いかもしれません。ただ、そこまで速度を気にする必要があるかは判りません。
dispatch_semaphore
いちばん軽量なのが dispatch_semaphore によるロックです。
これは今までのロックと性質が少し違っていて、ロックを通過できる処理数を指定できたり、アンロックされなくても一定時間が経過すると通過できるようになる機能も用意されています。
参考書籍について
今回の発表の中で「おすすめのサイトや書籍はありますか?」という問いには、まったく回答できませんでした。
というのも、いざ調べ始めてみると「原子性」も「スレッドセーフ」も、そう言えば言葉は聞いたことあっても、「じゃあ、実際のところそれって何なの?」という自分の問に僅かさえ答えを出せないありさまで、本を探せるだけの知識もなくて。
もはや手当たり次第に芋づる式にインターネットで調べていても、解らずいつしか C++ の std::atomic にまで彷徨い着いたり、ネット上の僅かな断片をつぎはぎしながら、完全迷子の状態でした。
そんな中でも岸川さんからいくつもアドバイスを頂きながら、お陰さまでなんとか無事ここまでたどり着くことができました。助かりました。
そんな訳で、おすすめの参考書籍は、勉強会に参加されていた他の方々が頼りです。
スレッド周りは「Java並行処理プログラミング」で勉強しました #idevjp
— ninjinkunさん (@ninjinkun) 2013年5月25日
マルチスレッドプログラミングは、「プログラミングWindows95」っていう本で学んだ気がする#idevjp
— あきお@拡張現実ライフさん (@akio0911) 2013年5月25日
Javaだけどこの本がマルチスレッドの話を理解するのにはお勧めの本らしい amazon.co.jp/gp/product/479…#idevjp
— nakamura001さん (@nakamura001) 2013年5月25日
こちらの Java の書籍はたしか @yuumi3 さんからも会場で教えて頂きました。
へー。個人的には結城浩さんの本がオススメです。 RT @nakamura001: Javaだけどこの本がマルチスレッドの話を理解するのにはお勧めの本らしい amazon.co.jp/gp/product/479…#idevjp
— 藤本直明/FUJIMOTO Naoakiさん (@naokiring) 2013年5月25日
#idevjp 結城先生 (hyuki) の本はマルチスレッドのデザインパターンの本ですね。原子性、可視性、可用性とかの話はあったかな?
— sawat1203さん (@sawat1203) 2013年5月25日
タイトルにまで書いてあるくらいだから当然マルチスレッドのこともわかりますよ『エキスパートObjective-Cプログラミング — iOS/OS Xのメモリ管理とマルチスレッド』 d.hatena.ne.jp/tatsu-zine/201… いまだけ480円だヨ #idevjp
— sakamoto.kazukiさん (@splhack) 2013年5月25日
そして、みなさまおすすめの流儀。
Immutable最高 #idevjp
— ninjinkunさん (@ninjinkun) 2013年5月25日
自分も処理するのはスレッドを1本にするのが良いなぁ #idevjp
— nakamura001さん (@nakamura001) 2013年5月25日
大西さん からも書籍の情報を頂きました。
[日記(IT)] iPhone勉強会いってきた の中で私信という形で頂きましたけど、こういう勉強好きな皆さんのためになる情報はどんどんオープンに行っちゃいましょう!
ほかの人の発表から思うこと
アクセシビリティ
ここぽんさんのフラットデザインのお話 の中で、アクセシビリティ、色盲のお話になって、みなさんそういうことも考慮されているんだなって関心させられました。
というのも、ちょうど数日前に自分のアプリのレビューにも「VoiceOver だと操作できないよ」と意見を頂いていて、それが頭の中にずっと留まっていたところだったのでした。
おかげさまでこのあたりも、調べてみたくなってきました。
デザインとしてのフラットデザイン
そしてメインのフラットデザインのお話にも、とても興味を惹かれました。
考え方と着眼点がとてもきれいで心地がいいです。さすがフラットデザインが出発点ではなくて、デザインとして導かれた結果がフラットだった(と思う)Llumino を制作した方だけあって、フラットデザインへの情熱とユーザー視点での追究は感動ものです。
自己満足を目的にしない、でもきっと自己の満足感も満たし得る、これこそが「デザイン」と呼ぶべき精神なのかもしれませんね。
そんなフラットデザインについてもっと感動したい人は、ここぽんさんの今回のスライドはもちろんのこと、同じくここぽんさんの Llumino ができるまで と、@nakamura001 さんが紹介されていたツイートの 2 つは必見です。
今日の #idevjp でフラットデザインが気になった人はこのMicrosoftがどういう思想でModern UIにしているのかをiOSのUIと比較して紹介してるページを読むとなんであんなUIしたのかが良く分かると思うよ msdn.microsoft.com/ja-jp/library/…
— nakamura001さん (@nakamura001) 2013年5月25日
自分もこれらを拝見して、フラットデザインに持つ印象が大きく生まれ変わりました。