natsuの秘密基地です
カレンダー
12 | 2025/01 | 02 |
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
カテゴリー
プロフィール
HN:
natsu
性別:
男性
趣味:
酒など
自己紹介:
ここに書かれていることはフィクションです。
[1] [2]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
キューを作って、実際使ってみた。
なんかデータを入れようということで、
NSDateとintを持つクラスを作り、
そのオブジェクトをキューに放り込んでみた。
で、取り出す。
放り込む人が5スレッド。
取り出す人が3スレッド。
ばらばらばらばら。
ログが入り乱れる。
放り込んだときと、
取り出したときにNSDateとintの内容を表示する。
で、取り出したとき、280個目あたりで落ちる。
どうも、NSDateの内容が無効になっているみたいだった。
気づくのにだいぶ時間がかかってしまった。
[NSDate date]で
かえってきたインスタンスをそのまま使っていたのが
まずかったんだと思う。
retainしてなかったんだな。
retainは大事だと思った。
頼りない感じだけど、
こんな感じでいんじゃね。
と、おもわれ。
できたてほやほや。
もうちょっと試さないといかんね。
PR
ロックをしたいとき、
どんな方法がとれるのか調べてみたけど、
以下の3つからどれにしようかといったところ。
・@synchronized
・POSIX mutex
・spin lock
なにも考えずにやりたい場合、
普通は@synchronizedでやればいいんだと思う。
POSIXのmutexも特になんも考えなくていいと思う。
spin lockはなんか、もっと低レベルの仕組みなんだと思う。
ドライバ書いたりする人はこんなの使うんでしょ。
ちょいと調べる限り、
ロックで待ってる間はビジーループで回るとかなんか書いてあるけど、
最近の実装じゃ、もっとうまいことやるでしょ。
きっと。
ほかのスレッドにCPU渡したり。
spin lockは実際に使わないと思うけど、
実験だし使ってみる。
計測計測。
ロックかけて
インクリメント
ロック外す
を10000回まわしてみる。
インクリメントすらスレッドセーフではない世の中。
何を信じればいいのか。
阿弥陀様を信じればいいと思うよ。
さて。計測計測。
一応すべての方法で、ロックがうまいこといくのは確認。
ロックなし
大体 0.035ms
@synchronized
大体1.84ms
POSIX mutex
大体0.65ms
spin lock
大体0.29ms
10000回連続でロックとアンロックをやってるので、
なんとかテクノロジ的なもので、
2回目以降は速くなるのかもしれないけど。
一回あたりのロックは
@synchronizedでも計測する意味が無いレベルだと思う。
とりあえず、
普通に使う分ではどれでも問題ない気はした。
すくなし、
@synchronizedなんて遅くて使えないよー。
なんてことは、いわないと思う。
クリティカルセクションを作る、
っていうときに、
@synchronizedはとても便利だと思う。
@synchronized(self)
{
for(int m=1 ; m<=5 ; m++)
{
NSLog(@"ID:%d SPEAK %d", threadID, m);
}
}
なんていう例は、
どこでだって見れるけども、
@synchronized(self)っていった場合、
そのメソッドがいくつかのスレッドから、
呼び出されることを想定しているんだと思う。
まあ、スレッドをつかってごにゃごにゃと、
この間からやってわけなんですが。
私のやつは、
スレッドごとにオブジェクトを一つ作成し、
そのオブジェクトに対してメッセージを送ることによって、
スレッド上の処理を動かす。
っていう感じになっているんだけども。
こんな動き方はすごいと思った。
あるスレッドで作ったオブジェクトは、
ほんとにそのスレッドに乗っかってるんだもの。
NSConnection経由でメッセージが送れる。
で、そんな感じのつくりだと、
@synchronized(self)
なんて無意味であることがわかる。
実際無意味だったし。
私のNSObjectを継承するクラスからうまれた、
かわいいインスタンスオブジェクトは
@synchronizedを意識した実装などしていないので、
この鍵はNSObjectがもっているはず。
なので、スレッドのファクトリで、
NSObject *lockObject
をもっておいて、
スレッドを作る際に渡しておく。
で、鍵をかけたいところで、
@synchronized(lockObject)
する。
2010-05-31 15:11:39.522 lockTest[4411:1d03] ID:0 SPEAK 1
2010-05-31 15:11:39.531 lockTest[4411:1d03] ID:0 SPEAK 2
2010-05-31 15:11:39.532 lockTest[4411:1d03] ID:0 SPEAK 3
2010-05-31 15:11:39.533 lockTest[4411:1d03] ID:0 SPEAK 4
2010-05-31 15:11:39.533 lockTest[4411:1d03] ID:0 SPEAK 5
2010-05-31 15:11:39.535 lockTest[4411:3603] ID:1 SPEAK 1
2010-05-31 15:11:39.535 lockTest[4411:3603] ID:1 SPEAK 2
2010-05-31 15:11:39.540 lockTest[4411:3603] ID:1 SPEAK 3
2010-05-31 15:11:39.540 lockTest[4411:3603] ID:1 SPEAK 4
2010-05-31 15:11:39.541 lockTest[4411:3603] ID:1 SPEAK 5
2010-05-31 15:11:39.544 lockTest[4411:3e03] ID:2 SPEAK 1
2010-05-31 15:11:39.545 lockTest[4411:3e03] ID:2 SPEAK 2
2010-05-31 15:11:39.545 lockTest[4411:3e03] ID:2 SPEAK 3
2010-05-31 15:11:39.546 lockTest[4411:3e03] ID:2 SPEAK 4
2010-05-31 15:11:39.546 lockTest[4411:3e03] ID:2 SPEAK 5
うん。めいめいのスレッドでちゃんと最後まで用を足す。
途中でママは呼ばない。
@synchronized。
こいつは勘なんだけども、
中の人はmutexのような気がする。
もし、頻繁にロック、アンロックするならば。
キューに構造体のポインタを押し込むような処理ならば、
処理自体よりロックの方が時間がかかるかもしれない。
と思った。
それも、たくさんの件数のデータを
押し込み、取り出しするんなら、
わりと馬鹿にならない時間がかかるかもしれない。
まだ試してみるべきことはある。