Entries

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Snow LeopardとNSOperationQueue

タグ: Objective-C Mac NSOperation

Snow LeopardでGrand Central Dispatchが導入され、はたしてNSOperationQueueはどうなったのか。

Mac Dev Center: NSOperationQueue ClassReference

In Mac OS X v10.6 and later, operation queues use the libdispatch library (also known as Grand Central Dispatch) to initiate the execution of their operations.

「Mac OS X 10.6以降のNSOperationQueueの中身はGrand Central Dispatchである」となるほど。

As a result, operations are always executed on a separate thread, regardless of whether they are designated as concurrent or non-concurrent operations.

「その結果、オペレーションはコンカレントであろうとなかろうと常に別のスレッドで実行されることになった」ってまじで。
ということは、以前書いたコンカレントオペレーション開始スレッド調査用コードをMac OS X 10.6.1で実行すると……

<NSThread: 0x10010aeb0>{name = (null), num = 1} main
<NSThread: 0x10010d650>{name = (null), num = 2} (1)Concurrent start
<NSThread: 0x100305e00>{name = (null), num = 3} (1)Concurrent thread ->
<NSThread: 0x10010d650>{name = (null), num = 2} (2)Noncurrent ->
<NSThread: 0x100305e00>{name = (null), num = 3} (1)Concurrent thread <-
<NSThread: 0x10010d650>{name = (null), num = 2} (2)Noncurrent main
<NSThread: 0x10010d650>{name = (null), num = 2} (2)Noncurrent <-
<NSThread: 0x10010e650>{name = (null), num = 4} (3)Concurrent start
<NSThread: 0x100305e00>{name = (null), num = 5} (3)Concurrent thread ->
<NSThread: 0x100305e00>{name = (null), num = 5} (3)Concurrent thread <-
<NSThread: 0x10010d650>{name = (null), num = 2} (4)Concurrent start
<NSThread: 0x10010eb60>{name = (null), num = 6} (4)Concurrent thread ->
<NSThread: 0x10010d650>{name = (null), num = 2} (5)Noncurrent ->
<NSThread: 0x10010eb60>{name = (null), num = 6} (4)Concurrent thread <-
<NSThread: 0x10010d650>{name = (null), num = 2} (5)Noncurrent main
<NSThread: 0x10010d650>{name = (null), num = 2} (5)Noncurrent <-
<NSThread: 0x10010e650>{name = (null), num = 4} (6)Concurrent start
<NSThread: 0x100306250>{name = (null), num = 7} (6)Concurrent thread ->

なるほど、Mac OS X 10.5.6では Concurrent start は常に「1つ前のオペレーションが終わったスレッド」で行われていたが、Mac OS X 10.6.1では常に「1つ前のオペレーションが終わったスレッド以外」で行われている。
これは「startがメインスレッドから呼ばれることを前提に実装」していた場合などに問題になるかもしれない。

あとは……依存関係を持つオペレーションのキャンセルについても何か変更があるようだ。

In Mac OS X v10.6 and later, if an operation is in a queue but waiting on unfinished dependent operations, those operations are subsequently ignored.

「Mac OS X 10.6以降では、依存するオペレーションが完了するのを待っているオペレーションをキャンセルした場合、その依存関係は無視して処理が進められる」
ほう。

#import <Foundation/Foundation.h>

@interface MyOperation : NSOperation
{
    int number;
}
@property int number;
@end

@implementation MyOperation
@synthesize number;
- (void)start
{
    NSLog(@"(%d) start", self.number);
    [super start];
}
- (void)main
{
    [NSThread sleepForTimeInterval:0.4];
    NSLog(@"(%d) end main", self.number);
}
- (void)cancel
{
    NSLog(@"(%d) cancel", self.number);
    [super cancel];
}
@end

int main()
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
    MyOperation *ops[3];
    for (int i = 0; i < 3; i++)
    {
        ops[i] = [[[MyOperation alloc] init] autorelease];
        ops[i].number = i;
    }
    [ops[1] addDependency:ops[0]]; // (1)は(0)に依存する
    [ops[2] addDependency:ops[1]]; // (2)は(1)に依存する
    for (int i = 0; i < 3; i++)
    {
        [queue addOperation:ops[i]]; 
    }
    [NSThread sleepForTimeInterval:0.1];
    [ops[1] cancel]; // (1)をキャンセル
    [queue waitUntilAllOperationsAreFinished];
    [pool drain];
}

Mac OS X 10.5.8でこれを実行すると、たとえ(1)をキャンセルしても、(1)が依存する(0)が終わるまで(2)は実行されない 。

.060 Hoge[880:1003] (0) start
.160 Hoge[880:10b] (1) cancel
.461 Hoge[880:1003] (0) end main
.463 Hoge[880:1103] (1) start
.464 Hoge[880:1003] (2) start
.865 Hoge[880:1003] (2) end main

Mac OS X 10.6.1で実行すると、(1)をキャンセルした時点で(2)が実行される 。

.076 Hoge[2879:1303] (0) start
.176 Hoge[2879:a0f] (1) cancel
.176 Hoge[2879:1503] (1) start
.177 Hoge[2879:2c03] (2) start
.479 Hoge[2879:1303] (0) end main
.578 Hoge[2879:2c03] (2) end main

「(2)は本当は(0)と(1)に依存しているんだけど、(1)が(0)に依存しているから、(1)に依存していれば(2)は(0)に依存しなくてもいいよね( ´∀`)」とか考えて実装していたらやばいかな。

スポンサーサイト

コメント

コメントの投稿

コメントの投稿
管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://idlysphere.blog66.fc2.com/tb.php/220-8df11c7e
この記事にトラックバックする(FC2ブログユーザー)

Appendix

タグ

Blog内検索

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。