iOSマルチタスク同時設計

3132 ワード

質問:現在1 wのタスクが実行され、すべての実行が完了した後にプロンプトが表示された場合、どうすればいいですか?
考え方1:最も直接的に考えるdispatch_グループ自体がタスクのセットのために設計されています
#define OPERATION_COUNT         10000
#define OPERATION_SLEEP_TIME    0.01f

- (void)myOperation:(NSInteger)index {
    [NSThread sleepForTimeInterval:OPERATION_SLEEP_TIME];    
}

- (void)runMyOperationsWithGCD {
    dispatch_group_t group = dispatch_group_create();
    for (int i = 0; i < OPERATION_COUNT; i++) {
        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
            [self myOperation:i];
        });
    }
    
    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
        NSLog(@"operations are finished");
    });
}

思考1:このコードは非常にさわやかに見えるはずですが、スレッドを作成しすぎたり、システムに大きな負担をかけたりして、最適化する必要があります.
質問:元の問題に基づいて最大10個の同時スレッドを制約するとしたら、何か良い方法がありますか?
構想2:iOSのNSOperationQueueを採用して、これはまったくこのような需要によって設計したので、とても使いやすいです
#define MAX_CONCURRENT_COUNT 10
#define OPERATION_COUNT     10000
#define OPERATION_SLEEP_TIME    0.1f

- (void)myOperation:(NSInteger)index {
    NSLog(@"enter myOperation:%ld, thread:%@", (long)index, [NSThread currentThread]);
    [NSThread sleepForTimeInterval:OPERATION_SLEEP_TIME];    
}

- (void)runMyOPerationsWithNSOperation {
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    queue.maxConcurrentOperationCount = MAX_CONCURRENT_COUNT;// 
    for (int i = 0; i < OPERATION_COUNT; i++) {
        [queue addOperationWithBlock:^{
            [self myOperation:i];
        }];
    }
        
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [queue waitUntilAllOperationsAreFinished];// 
        NSLog(@"operations are finished");
    });
}

思考2:個人的には、これが最も便利な方法であり、簡単明瞭で、あまりスレッドや冗長なコードがないと思います.
質問:NSOperationを使わなければ、また何かいい方法がありますか?
考え方3:信号量制御による同時化、考え方1のdispatch_グループタスク完了後の通知を実現
#define MAX_CONCURRENT_COUNT 10
#define OPERATION_COUNT     10000
#define OPERATION_SLEEP_TIME    0.1f

- (void)myOperation:(NSInteger)index {
    NSLog(@"enter myOperation:%ld, thread:%@", (long)index, [NSThread currentThread]);
    [NSThread sleepForTimeInterval:OPERATION_SLEEP_TIME];
}

- (void)runMyOperationsWithSemaphore {
    // , 10
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(MAX_CONCURRENT_COUNT);
    dispatch_group_t group = dispatch_group_create();
    for (int i = 0; i < OPERATION_COUNT; i++) {
        //wait ,semaphore , semaphore 0 wait
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
            [self myOperation:i];
            // , semaphore, 
            dispatch_semaphore_signal(semaphore);
        });
    }

    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
        NSLog(@"operations are finished");
    });
}


思考3:この方式は実は構想1の基礎の上で信号量の同時制限を増加して、1種の簡単な改善に相当します.
最後に、最も伝統的なNSThreadを採用すれば、信号量と協力して、マルチタスクの同時実行を実現することができるが、どのようにすべてのタスクが実行済みであるかを判断するには、カウントを通過する方法しか考えられず、より良い方法は考えられなかった.もし皆さんがもっと良い方法があれば、伝言、私信を歓迎します.
最後にdemo、アドレスを添付します