GCD provides two ways to support dispatch queue synchronization, that is, dispatch groups and semaphores.
Dispatch (dispatchGroup)
1. Create a dispatch group
dispatch_group_t group = Dispatch_group_create ();
2. Start the block in the dispatch queue to associate to the group
Dispatch_group_async (group, queue, ^{
。。。
});
3. Wait for the block association to complete, or you can set the timeout parameter
Dispatch_group_wait (group, dispatch_time_forever);
4. Notifies the group that a block is called when the block associated by the group is executed. Similar to Dispatch_barrier_async.
Dispatch_group_notify (group, queue, ^{
。。。
});
5. Manually manage the running state (or count) of the block associated with the group, the number of entry and exit group must match
Dispatch_group_enter (group);
Dispatch_group_leave (group);
So the following two kinds of calls are actually equivalent,
A
Dispatch_group_async (group, queue, ^{
。。。
});
B
Dispatch_group_enter (group);
Dispatch_async (Queue, ^{
。。。
Dispatch_group_leave (group);
});
Therefore, you can use Dispatch_group_enter, Dispatch_group_leave and dispatch_group_wait to achieve synchronization, specific examples: http://stackoverflow.com/ questions/10643797/wait-until-multiple-operations-executed-including-completion-block-afnetworki/10644282# 10644282.
Second, dispatch signal (dispatch semaphore)
1. Create semaphores to set the number of resources for the semaphore. 0 means no resources, and calling Dispatch_semaphore_wait waits immediately.
dispatch_semaphore_t semaphore = dispatch_semaphore_create (0);
2. Wait for the signal, you can set the timeout parameter. The function returns 0 to be notified, not 0 for timeouts.
Dispatch_semaphore_wait (semaphore, dispatch_time_forever);
3. The notification signal, if the waiting thread is awakened, returns non 0, otherwise returns 0.
Dispatch_semaphore_signal (semaphore);
Finally, return to the example of generating a consumer, using the dispatch semaphore is how to achieve synchronization:
dispatch_semaphore_t sem = dispatch_semaphore_create (0);
Dispatch_async (Dispatch_get_global_queue (dispatch_queue_priority_default, 0), ^{//consumer queue
while (condition) {
if (dispatch_semaphore_wait (SEM, dispatch_time (Dispatch_time_now, 10*nsec_per_sec))//wait 10 seconds
Continue
Get the data
}
});
Dispatch_async (Dispatch_get_global_queue (dispatch_queue_priority_default, 0), ^{//producer queue
while (condition) {
if (!dispatch_semaphore_signal (SEM))
{
Sleep (1); Wait for a while
Continue
}
Notification successful
}
});