correct way to wait for dispatch_semaphore in order to wait for many async tasks to complete

我只是一个虾纸丫 提交于 2019-12-06 11:29:32

问题


I have an asynchronous method longRunningMethodOnObject:completion:

this method receives an object of type 'Object' - does work with its data and then calls the completion handler.

I need to call many different "longRunningMethods" and wait for all to complete.

I would like all of the "longRunningMethodOnObject" to run asynchronously (parallel) to each other in the "for" loop. (I am not certain if the "longRunningMethodOnObject" runs in serial to each other but this is more of a general question)

I'm not sure I have created a proper semaphore and would appreciate an explanation on the proper way to synchronize between them.

The code for the wrapper function is as follows:

-(void)applyLongRunningOperationOnObjectInArray:(NSArray *)theObjects completion:(completion)block
{
// offsetting to worker thread in my object
  dispatch_async(self.myQueue,^{
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); //Not sure if this should be here or in the for loop
    for(Object *ob in theObjects)
    {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); // the semaphore for the "for" loop - should this be here? or above the for loop
      [GlobalObject longRunningMethodOnObject:ob completion:^{ // would like each call to be independant of previous call in for loop
        dispatch_semaphore_signal(semaphore); // signaling that it completed
      }];
    }
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); // would like to wait here for each semaphore 
    block(); // invoke the completion handler
  });
}

回答1:


I suppose you could use dispatch_semaphore in this case, but dispatch groups may make the application logic simpler:

NSArray *theObjects = @[@"Apple",@"Orange",@"Peach"];
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t _myQueue = dispatch_queue_create("com.cocoafactory.DispatchGroupExample",
                                                      0);
for( id ob in theObjects ) {
    dispatch_group_async(group, _myQueue, ^{
        //  do some long running task.
    });
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

//  now do whatever should be done after
//  all of your objects are processed
//  in your case block()

The Concurrency Programming Guide as a bit on this topic. Scroll down to 'Waiting on Groups of Queued Tasks"

To answer the question about whether tasks are execute concurrently in the queue or not, it depends. In the example above, _myQueue is a serial queue. The global named queues are concurrent. You can also create concurrent queues with the DISPATCH_QUEUE_CONCURRENT queue type as of iOS 5.



来源:https://stackoverflow.com/questions/19464356/correct-way-to-wait-for-dispatch-semaphore-in-order-to-wait-for-many-async-tasks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!