manpagez: man pages & more
man dispatch_apply(3)
Home | html | info | man
dispatch_apply(3)        BSD Library Functions Manual        dispatch_apply(3)


NAME

     dispatch_apply -- schedule blocks for iterative execution


SYNOPSIS

     #include <dispatch/dispatch.h>

     void
     dispatch_apply(size_t iterations, dispatch_queue_t queue,
         void (^block)(size_t));

     void
     dispatch_apply_f(size_t iterations, dispatch_queue_t queue,
         void *context, void (*function)(void *, size_t));


DESCRIPTION

     The dispatch_apply() function provides data-level concurrency through a
     "for (;;)" loop like primitive:

     dispatch_queue_t the_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
     size_t iterations = 10;

     // 'idx' is zero indexed, just like:
     // for (idx = 0; idx < iterations; idx++)

     dispatch_apply(iterations, the_queue, ^(size_t idx) {
             printf("%zu\n", idx);
     });

     Like a "for (;;)" loop, the dispatch_apply() function is synchronous.  If
     asynchronous behavior is desired, please wrap the call to
     dispatch_apply() with a call to dispatch_async() against another queue.

     Sometimes, when the block passed to dispatch_apply() is simple, the use
     of striding can tune performance.  Calculating the optimal stride is best
     left to experimentation.  Start with a stride of one and work upwards
     until the desired performance is achieved (perhaps using a power of two
     search):

     #define STRIDE 3

     dispatch_apply(count / STRIDE, queue, ^(size_t idx) {
             size_t j = idx * STRIDE;
             size_t j_stop = j + STRIDE;
             do {
                     printf("%zu\n", j++);
             } while (j < j_stop);
     });

     size_t i;
     for (i = count - (count % STRIDE); i < count; i++) {
             printf("%zu\n", i);
     }


IMPLIED REFERENCES

     Synchronous functions within the dispatch framework hold an implied ref-
     erence on the target queue. In other words, the synchronous function bor-
     rows the reference of the calling function (this is valid because the
     calling function is blocked waiting for the result of the synchronous
     function, and therefore cannot modify the reference count of the target
     queue until after the synchronous function has returned).

     This is in contrast to asynchronous functions which must retain both the
     block and target queue for the duration of the asynchronous operation (as
     the calling function may immediately release its interest in these
     objects).


FUNDAMENTALS

     Conceptually, dispatch_apply() is a convenient wrapper around
     dispatch_async() and a semaphore to wait for completion.  In practice,
     the dispatch library optimizes this function.

     The dispatch_apply() function is a wrapper around dispatch_apply_f().


CAVEATS

     Unlike dispatch_async(), a block submitted to dispatch_apply() is
     expected to be either independent or dependent only on work already per-
     formed in lower-indexed invocations of the block. If the block's index
     dependency is non-linear, it is recommended to use a for-loop around
     invocations of dispatch_async().


SEE ALSO

     dispatch(3), dispatch_async(3), dispatch_queue_create(3),
     dispatch_semaphore_create(3)

Darwin                            May 1, 2009                           Darwin

Mac OS X 10.8 - Generated Sat Aug 25 07:15:12 CDT 2012
© manpagez.com 2000-2021
Individual documents may contain additional copyright information.