GCD

Introduction to the

Grand Central Dispatch (GCD) is a multi-core programming solution developed by Apple. It is a set of PURE C apis for optimizing applications to support multicore processors and other symmetric multiprocessing systems. It is a concurrent task executed on a thread pool basis.

The advantages of the GCD

  • GCD supports multi-core parallel computing
  • GCD automatically manages the thread lifecycle (thread creation, raising, waiting, and destruction)
  • The user only needs to tell the GCD to perform the task

Tasks and queues

task

A task is the code that needs to be executed in a thread. In GCD, even code executed in blocks is a task. Tasks are classified into sync and Async.

  • Synchronization Task (sync): Synchronously adds a task to a queue. It waits until the previous task is completed. The added task is executed only when the previous task is completed. Can not be executed in a new thread, does not have the ability to open a new thread.
  • Asynchronous task: Asynchronously adds a task to a queue. The task is added to a queue without waiting for the completion of previous tasks. Can be executed in a new thread, with the ability to open up new threads.Note: The ability to start a new thread does not necessarily mean that a new thread is started

The queue

A task queue is a list of tasks to be executed following the first-in, first-out (FIFO) IFFO principle. In the GCD, there are Serial Dispatch queues and Concurrent Dispatch queues, also known as Concurrent queues.

  • Serial Dispatch QueueOnly:Start a threadOnly one task can be executed at a time. After the task is executed, the next task can be executed.
  • Concurrent Dispatch Queue: Allows multiple tasks to be executed at the same time, and enables multiple threads to execute multiple tasks.Note: Concurrent queues are only valid for asynchronous functions.

A special queue

  • Serial main queue: A serial main queue in which the synchronization task cannot be called again in the main thread because it would block, but can be called in other threads
  • Global concurrent queue: A global concurrent queue

Creation of queues and tasks

Create a queue

  • Creating a serial queue
// The first argument is the queue name, custom; //DISPATCH_QUEUE_SERIAL = NULL, Dispatch_queue_t queue = dispatch_queue_CREATE ("shifx", DISPATCH_QUEUE_SERIAL);Copy the code
  • Creating concurrent queues
// The first argument is the queue name, custom; The second parameter indicates serial or concurrent dispatch_queue_t queue = dispatch_queue_create("shifx", DISPATCH_QUEUE_CONCURRENT);Copy the code

Task creation

  • Creating a Synchronization Task
Dispatch_sync (queue, ^{});Copy the code
  • Creating an Asynchronous Task
Dispatch_async (queue, ^{});Copy the code

Queue and task summary

To sum up, we can get a total of four combinations plus two special queues, i.e

  • Serial queue + synchronous execution
  • Concurrent queue + synchronous execution
  • Serial queue + asynchronous execution
  • Concurrent queue + asynchronous execution
  • Serial main queue
  • Global concurrent queue

Queues are used in combination with tasks

Serial queue + synchronous execution

Code implementation

-(void)serialSysncText {dispatch_queue_t serial = dispatch_queue_create("shifx", DISPATCH_QUEUE_SERIAL); NSLog(@" Serial synchronization task starts "); dispatch_sync(serial, ^{ sleep(1); for (int i = 0; i<3; I ++) {NSLog(@" serial synchronization task 1 = %d", I); }}); dispatch_sync(serial, ^{ sleep(1); for (int i = 0; i<3; I ++) {NSLog(@" serial synchronization task 2 = %d", I); }}); NSLog(@" Serial synchronization task terminated "); }Copy the code

The results

From the results, we can see that the synchronization tasks in the serial queue are executed in sequence.

Concurrent queue + synchronization task

Code implementation

-(void)concurrentAsysncText {dispatch_queue_t concurrent = dispatch_queue_create("shifx", DISPATCH_QUEUE_CONCURRENT); NSLog(@" concurrent synchronization task started "); dispatch_sync(concurrent, ^{ sleep(1); for (int i = 0; i<3; I ++) {NSLog(@" concurrent task 1 = %d", I); }}); dispatch_sync(concurrent, ^{ sleep(1); for (int i = 0; i<3; I ++) {NSLog(@" concurrent task 2 = %d", I); }}); NSLog(@" Concurrent synchronization task terminated "); }Copy the code

The results

From the results, so do synchronization tasks performed by concurrent queuesExecute in sequenceBecause they’re all hereExecuted in the main threadNo new thread is started. Interested partners can print the thread to see.

Serial queue + asynchronous execution

Code implementation

-(void)serialAsysncText {dispatch_queue_t serial = dispatch_queue_create("shifx", DISPATCH_QUEUE_SERIAL); NSLog(@" serial asynchronous task starts "); dispatch_async(serial, ^{ for (int i = 0; i<3; i++) { sleep(1); NSLog(@" serial asynchronous task 1 = %d", I); NSLog(@" currentThread: %@",[NSThread currentThread]); }}); dispatch_async(serial, ^{ for (int i = 0; i<3; i++) { sleep(1); NSLog(@" serial asynchronous task 2 = %d", I); NSLog(@" currentThread: %@",[NSThread currentThread]); }}); NSLog(@" serial asynchronous task terminated "); }Copy the code

The results

As you can see from the results,

  • All asynchronous tasks are executed after the serial asynchronous task is printed.
  • A new thread is started, but only one thread is started.
  • Asynchronous tasks in serial queues are also executed in sequential order.

Concurrent queue + asynchronous execution

Code implementation

-(void)concurrentAsysncText {dispatch_queue_t concurrent = dispatch_queue_create("shifx", DISPATCH_QUEUE_CONCURRENT); NSLog(@" concurrent asynchronous task starts "); dispatch_async(concurrent, ^{ for (int i = 0; i<3; i++) { sleep(1); NSLog(@" concurrent asynchronous task 1 = %d", I); NSLog(@" currentThread: %@",[NSThread currentThread]); }}); dispatch_async(concurrent, ^{ for (int i = 0; i<3; i++) { sleep(1); NSLog(@" concurrent asynchronous task 2 = %d", I); NSLog(@" currentThread: %@",[NSThread currentThread]); }}); NSLog(@" Concurrent asynchronous task ends "); }Copy the code

The results

Based on the results of the run,

  • All asynchronous tasks are executed after the printing and concurrent asynchronous tasks end.
  • The concurrent queue opens two new threads due to two asynchronous tasks
  • The two asynchronous tasks are executed in no order

Main queue + synchronization task

The main queue synchronization task is invoked on the main thread

Since the main queue is a serial queue, it cannot invoke the main queue synchronization task in the main thread, as shown belowThe cause of the crash is that the synchronization task is in the main thread, and it needs to wait for the main thread to complete, and the main thread needs to wait for the method to complete.The two wait for each other to deadlockSo it crashed.

Other threads call the main queue synchronization task

code

/ / use the NSThread detachNewThreadWithBlock method will create a thread [NSThread detachNewThreadWithBlock: ^ {[self mainSysncText];}]. -(void)mainSysncText {NSLog(@" currentThread: %@",[NSThread currentThread]); dispatch_sync(dispatch_get_main_queue(), ^{ for (int i = 0; i<2; i++) { sleep(1); NSLog(@" primary queue synchronization task 1 = %d", I); NSLog(@" currentThread: %@",[NSThread currentThread]); }}); dispatch_sync(dispatch_get_main_queue(), ^{ for (int i = 0; i<2; i++) { sleep(1); NSLog(@" primary queue synchronization task 2 = %d", I); NSLog(@" currentThread: %@",[NSThread currentThread]); }}); }Copy the code

The execution result

Main queue + asynchronous task

Since the primary queue is a serial queue, the primary queue + asynchronous task is equivalent to the serial queue + asynchronous task

code

-(void)mainAsysncText {NSLog(@" currentThread: %@",[NSThread currentThread]); NSLog(@" main queue asynchronous task started "); dispatch_async(dispatch_get_main_queue(), ^{ for (int i = 0; i<2; i++) { sleep(1); NSLog(@" primary queue async task 1 = %d", I); NSLog(@" currentThread: %@",[NSThread currentThread]); }}); dispatch_async(dispatch_get_main_queue(), ^{ for (int i = 0; i<2; i++) { sleep(1); NSLog(@" primary queue async task 2 = %d", I); NSLog(@" currentThread: %@",[NSThread currentThread]); }}); NSLog(@" main queue asynchronous task ends "); }Copy the code

The results

Effect equivalent toSerial queue + asynchronous task