Apple Developer Connection
Advanced Search
Member Login Log In | Not a Member? Contact ADC

< 前ページ次ページ >

スレッド化

Objective-Cでは、スレッド同期と例外処理をサポートしています。これらについては、この章と例外処理で説明されています。これらの機能のサポートを有効にするには、GCC (GNU Compiler Collection) v3.3以降の-fobjc-exceptionsスイッチを使用します。

注: プログラムでこれらの機能のいずれかを使用すると、Mac OS X v10.3以降でのみ実行可能なアプリケーションになります。それ以前のバージョンのソフトウェアでは、例外処理と同期のランタイムサポートがないからです。

スレッド実行の同期

Objective-Cでは、アプリケーションのマルチスレッド処理をサポートしています。これは、2つのスレッドが同時に同じオブジェクトを変更しようとする可能性があること、プログラムに深刻な問題を引き起こす可能性がある状況を意味します。同時に複数のスレッドによって実行されないようにコードの一部を保護できるように、Objective-Cでは@synchronized()ディレクティブを提供しています。

@synchronized()ディレクティブは、コードの一部を1つのスレッドで使用するようにロックします。スレッドが保護コードを抜け出すまで、つまり、@synchronized()ブロックの最後の文を通過するまで、他のスレッドはブロックされます。

@synchronized()ディレクティブは、唯一の引数としてselfを含む任意のObjective-Cオブジェクトを受け取ります。このオブジェクトは、相互排他(mutual exclusion)セマフォまたはミューテックス(mutex)と呼ばれています。これにより、スレッドはコードの一部を他のスレッドに使用されないようにロックできます。プログラムの個別のクリティカルセクションを保護するには、別々のセマフォを使用する必要があります。アプリケーションのマルチスレッド処理を開始する前に、すべての相互排他オブジェクトを作成して、競合状態を回避するのが最も安全です。

リスト 10-1に、ミューテックスにselfを使って、カレントオブジェクトのインスタンスメソッドへのアクセスを同期するコード例を示します。selfの代わりにクラスオブジェクトを使用して、同様の方法で対応するクラスのクラスメソッドを同期できます。もちろん、後者の例では、すべての呼び出し側で共有しているクラスオブジェクトは1つのみのため、クラスメソッドを実行できるスレッドは一度に1つだけです。

リスト 10-1  selfを使ってメソッドをロックする

- (void)criticalMethod
{
    @synchronized(self) {
        // クリティカルコード。
        ...
    }
}

リスト 10-2では、現在のセレクタ、_cmdをミューテックスとして使用しています。このような同期は、同期しようとしているメソッドが一意の名前を持つ場合にかぎり有効です。他のオブジェクトやクラスは、現在のメソッドが終了するまで異なるメソッドを同じ名前では実行できないからです。

リスト 10-2  _cmdを使ってメソッドをロックする

- (void)criticalMethod
{
    @synchronized(NSStringFromSelector(_cmd)) {
        // クリティカルコード。
        ...
    }
}

リスト 10-3では、一般的な方法を示します。コードでは、クリティカルなプロセスを実行する前に、Accountクラスからセマフォを取得し、これを使ってクリティカルセクションをロックしています。Accountクラスは、自身のinitializeメソッド内にセマフォを作成できます。

リスト 10-3  カスタムセマフォを使ってメソッドをロックする

Account *account = [Account accountFromString:[accountField stringValue]];
 
// セマフォを取得する。
id accountSemaphore = [Account semaphore];
 
@synchronized(accountSemaphore) {
    // クリティカルコード。
    ...
}

Objective-Cの同期機能は、再帰コードおよび再入可能コードをサポートしています。スレッドは1つのセマフォを再帰的に複数回使用できます。そのスレッドが取得したすべてのロックを解放するまで(つまり、すべての@synchronized()ブロックが正常終了するか、例外によって終了するまで)、他のスレッドはその使用をブロックされます。

@synchronized()ブロックのコードが例外をスローすると、Objective-Cランタイムがその例外をキャッチし、セマフォを解放して(その結果、他のスレッドが保護コードを実行できます)、その例外を次の例外ハンドラに再スローします。



< 前ページ次ページ >


Last updated: 2007-10-31




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.
Get information on Apple products.
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Copyright © 2007 Apple Inc.
All rights reserved. | Terms of use | Privacy Notice