I am newer to iPhone development and going through GCD concept for multithreading.
'dispatch_queue_t' creates a serial queue and I have read that a serial queue will only execute one job at a time. GCD is intended to execute multiple tasks simultaneously then why serial queue even exist ?
For example, I want to do 2 task. Task A and Task B. I create one serial queue for executing both these tasks. I am doing this in the main queue. Here is the code what I am doing:
dispatch_queue_t my_serial_queue = dispatch_queue_create("queue_identifier", 0);
dispatch_sync(my_serial_queue, ^{
NSLog(@"Task 1");
});
dispatch_sync(my_serial_queue, ^{
NSLog(@"Task 2");
});
Now, As per the rule, both the task will execute serially as it is serial queue i.e. Task A is executed first and then after Task A is finished, Task B will be executed. And also it is giving me the same output in log.
So, my question is, what if I want to execute both the tasks simultaneously ? If the answer of this question is to create another serial queue for Task B then the code should be structured like this:
dispatch_queue_t my_serial_queue_1 = dispatch_queue_create("queue_identifier_1", 0);
dispatch_queue_t my_serial_queue_2 = dispatch_queue_create("queue_identifier_2", 0);
dispatch_sync(my_serial_queue_1, ^{
NSLog(@"Task 1");
});
dispatch_sync(my_serial_queue_2, ^{
NSLog(@"Task 2");
});
I am getting the same output. Reason is I am using 'dispatch_sync' call instead of 'dispatch_async' call. But as I am running both the tasks in different queues, shouldn't they execute simultaneously ? If not, then why should we create a different queue ? I might have used the same queue by 'dispatch_async' call for executing both the tasks simultaneously.
I really need answer of this question because, before designing structure of my multi-tasking Apps in future, it will guide me better.
Your confusion is pretty much entirely because you're using dispatch_sync. dispatch_sync is not a tool for getting concurrent execution, it is a tool for temporarily limiting it for safety.
Once you're using dispatch_async, you can get concurrency either by having more than one queue, or by using concurrent queues. The purpose of using serial queues in this context is to control which work is done simultaneously.
Consider the following very silly example:
__block void *shared = NULL;
for (;;) {
dispatch_async(aConcurrentDispatchQueue, ^{
shared = malloc(128);
free(shared);
}
}
this will crash, because eventually, two of the concurrently executing blocks will free 'shared' in a row. This is a contrived example obviously, but in practice, nearly all shared mutable state must not be changed concurrently. Serial queues are your tool for making sure that you do that.
Summarizing: