プログラミング > 全般 - Mac >

Grand Central Dispatch その5 semaphore


ディスパッチまだまだ続きます。でも、処理の高速化ってことを考えると、GCDよりOpenCLのほうが効果的なんじゃないかって気がしてきました。まあ、Airでしか試してないからだと思いますけど。

ディスパッチはいままでの並列処理の方法と比べるとシンプルで簡単だ、なんて書かれていたりしますけど、どうやらセマフォは欠かせないようで、ディスパッチにもあります。

先にあれこれ書くのがめんどくさくなってきたので、とりあえずサンプルコードから。

#include <stdio.h>
#include <unistd.h>
#include <dispatch/dispatch.h>

int main (int argc, const char * argv[]) {
    
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
    
    for (int i = 0; i < 10; i++) {
        dispatch_group_async(group, queue, ^{
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            //クリティカルセクション開始
            printf("start %d\n", (int)i);
            usleep(10000);
            printf("end %d\n", (int)i);
            //クリティカルセクション終了
            dispatch_semaphore_signal(semaphore);
        });
    }
    
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    
    dispatch_release(semaphore);
    dispatch_release(group);
    
    return 0;
}

ディスパッチのセマフォの使い方としてはまず、dispatch_semaphore_createでセマフォのオブジェクトdispatch_semaphore_tを作ります。引数にはセマフォの旗の数を指定できます。0だと一回も進入できなくなってしまいますので1以上を指定します。

そして、クリティカルセクションをdispatch_semaphore_wait〜dispatch_semaphore_signalで囲みます。それぞれ引数にセマフォオブジェクトを渡します。waitでは進入できない時に待つ時間を指定できて、DISPATCH_TIME_FOREVERなら永久に待ちます。

サンプルコードを実行すると、クリティカルセクション開始〜終了としているところは同時に実行されず、printfでstartとendがセットで0から9まで順番に出力されます。もし、セマフォ関連の関数を排除したら、startのあとにスリープさせていますので、startが10個出力された後に、endが10個出力されるはずです。

という感じで、ディスパッチのキューに直接ブロックを渡す関係は以上で終わりです。ちなみに、キューにブロックを渡してしまうと後からキャンセルが出来なかったりしますのでご注意を。

その処理のキャンセルとかも含めて、ディスパッチにはソースって仕組みも用意されていますので、次回以降見ていこうと思います。

トラックバック(0)

このブログ記事を参照しているブログ一覧: Grand Central Dispatch その5 semaphore

このブログ記事に対するトラックバックURL: http://objective-audio.jp/oa80/mt-tb.cgi/125

コメントする


画像の中に見える文字を入力してください。