Reputation: 12499
I need to perform three tasks that are independent one from each other, so I'd like to execute them concurrently. But I need them all to have finished to notify another object. AFAIK, *dispatch_apply* creates concurrent threads, but it iterates a collection or an array of objects and performs the same task a number of loops, and I want to perform a different task for each thread. Is it possible to do what I want by using GCD? If not, what should be the best way?
Thanks!
Upvotes: 3
Views: 1495
Reputation: 437422
I know you asked about GCD, but NSOperationQueue
is another possibility. For example:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 3;
// create my completion operation (which will be added to the queue later, once
// the dependencies with all of the other operations has been established)
NSBlockOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"All done");
}];
// let's add our three operations
NSBlockOperation *operation;
operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"starting task 1");
sleep(5);
NSLog(@"stopping task 1");
}];
[completionOperation addDependency:operation];
[queue addOperation:operation];
operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"starting task 2");
sleep(4);
NSLog(@"stopping task 2");
}];
[completionOperation addDependency:operation];
[queue addOperation:operation];
operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"starting task 3");
sleep(6);
NSLog(@"stopping task 3");
}];
[completionOperation addDependency:operation];
[queue addOperation:operation];
// now let's add the completion operation (which has been configured as dependent
// upon the other operations
[queue addOperation:completionOperation];
There are tons of different ways of tackling this problem, but NSOperationQueue
is another option. The Concurrency Programming Guide discusses all of the options.
Upvotes: 4
Reputation: 41632
Dispatch Groups are what you need. Look at the GCD functions. What you will do is create the group and a concurrent queue (or use thee standard ones). Associate the three operations (blocks) with the dispatch_group, then create a forth block, and have that block do a dispatch_group_wait (typing names by memory), then when that returns, it can post a 'success' message to some other object. Put the block with the wait into any concurrent queue.
I do exactly this in my app.
Upvotes: 4
Reputation: 27984
Use a dispatch_group
. The Concurrency Programming Guide gives one example, and there is more API that might also help you.
Create a dispatch group using dispatch_group_create
.
Put each "task" in the group by enqueuing it using dispatch_group_async
.
(Or, manually tell GCD when each task starts and stops, using dispatch_group_enter
and dispatch_group_leave
.)
To run a block when all tasks in the group have completed, enqueue it using dispatch_group_notify
.
(Or, in the unlikely case that the design of your app allows you to wait synchronously, use dispatch_group_wait
instead.)
When you're done with the group, dispatch_release
it.
Upvotes: 6