The queue

Features: FifO data structure

Category: Serial queue Parallel queue Global parallel queue Primary queue

Task: the code that block code is about to execute sync async

The simple understanding of multithreading is to open up other threads in addition to the main thread and increase the execution efficiency. In plain English, code has multiple execution paths. For a single-core iOS system, multithreading is actually concurrent rather than multi-core parallelism. On single-core iOS, threads switch back and forth per unit of time, giving the illusion of parallelism.

GCD is packaged based on THE C language, and only usage is discussed here. The usage is to create a queue and add tasks to the queue for execution.

How do I create a queue?

Serial queuesdispatch_queue_t queue1 = dispatch_queue_create("testQueue", DISPATCH_QUEUE_SERIAL); Primary queue Special serial queue - all tasks in the primary queue are executed on the main threaddispatch_queue_tmainQueue = dispatch_get_main_queue(); Parallel linesdispatch_queue_t queue2 = dispatch_queue_create("queue2", DISPATCH_QUEUE_CONCURRENT); Global parallel queuedispatch_queue_t queueAll = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
Copy the code

task

Tasks can be executed synchronously or asynchronously

Synchronization does not have the ability to start threadsdispatch_sync(queue, ^{
    <#code#>}); Asynchrony has the ability to start threads, and whether threads are started or not must be combined with queuesdispatch_async(queue1, ^{
    <#code#>
});
Copy the code

Task and queue combination page table screenshot below :(since global concurrent queues can also be considered concurrent queues, they are not considered)

Synchronous + serial queue

Features: No new threads are opened and tasks are executed in sequence

- (void)syncSerial {
    NSLog(The current thread is: %@[NSThread currentThread]);  // The current thread
    NSLog(@ "start");
    // Create a serial queue here
    dispatch_queue_t queue = dispatch_queue_create("testQueue", DISPATCH_QUEUE_SERIAL);
    
    dispatch_sync(queue, ^{
        // Append task 1
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(I am task 1, from thread: %@[NSThreadcurrentThread]); }});dispatch_sync(queue, ^{
        // Append task 2
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(I am task 2, from thread: %@[NSThreadcurrentThread]); }});dispatch_sync(queue, ^{
        // Add task 3
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog("I am task 3, from thread: %@"[NSThreadcurrentThread]); }});NSLog(@ "end");
}
Copy the code

Print result:

2019- 01- 23 09:49:41.098930+0800Multithreaded demo [922:34551] Current thread is: <NSThread: 0x604000073a80>{number = 1, name = main}
2019- 01- 23 09:49:41.099092+0800Multithreaded demo [922:34551] start2019- 01- 23 09:49:43.100540+0800Multithreaded demo [922:34551I am task 1, from thread: <NSThread: 0x604000073a80>{number = 1, name = main}
2019- 01- 23 09:49:45.101953+0800Multithreaded demo [922:34551I am task 1, from thread: <NSThread: 0x604000073a80>{number = 1, name = main}
2019- 01- 23 09:49:47.103420+0800Multithreaded demo [922:34551I am task 2, from thread: <NSThread: 0x604000073a80>{number = 1, name = main}
2019- 01- 23 09:49:49.104828+0800Multithreaded demo [922:34551I am task 2, from thread: <NSThread: 0x604000073a80>{number = 1, name = main}
2019- 01- 23 09:49:51.106334+0800Multithreaded demo [922:34551I am task 3, from thread: <NSThread: 0x604000073a80>{number = 1, name = main}
2019- 01- 23 09:49:53.106785+0800Multithreaded demo [922:34551I am task 3, from thread: <NSThread: 0x604000073a80>{number = 1, name = main}
2019- 01- 23 09:49:53.106981+0800Multithreaded demo [922:34551End]Copy the code

Second, synchronization + concurrent queue

Features: No new threads are opened and tasks are executed in sequence

NSLog(Current thread %@[NSThread currentThread]);  // Prints the current thread
    NSLog(@ "start");
    
    dispatch_queue_t queue = dispatch_queue_create("testQueue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_sync(queue, ^{
        // Append task 1
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(I am task 1, from thread: %@[NSThreadcurrentThread]); }});dispatch_sync(queue, ^{
        // Append task 2
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(I am task 2, from thread: %@[NSThreadcurrentThread]); }});dispatch_sync(queue, ^{
        // Add task 3
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog("I am task 3, from thread: %@"[NSThreadcurrentThread]); }});NSLog(@ "end");
Copy the code

Print result:

2019- 01- 23 10:02:31.505366+0800Multithreaded demo [1053:44225] current thread <NSThread: 0x600000064d00>{number = 1, name = main}
2019- 01- 23 10:02:31.505740+0800Multithreaded demo [1053:44225] start2019- 01- 23 10:02:33.506119+0800Multithreaded demo [1053:44225I am task 1, from thread: <NSThread: 0x600000064d00>{number = 1, name = main}
2019- 01- 23 10:02:35.507093+0800Multithreaded demo [1053:44225I am task 1, from thread: <NSThread: 0x600000064d00>{number = 1, name = main}
2019- 01- 23 10:02:37.507964+0800Multithreaded demo [1053:44225I am task 2, from thread: <NSThread: 0x600000064d00>{number = 1, name = main}
2019- 01- 23 10:02:39.508543+0800Multithreaded demo [1053:44225I am task 2, from thread: <NSThread: 0x600000064d00>{number = 1, name = main}
2019- 01- 23 10:02:41.509973+0800Multithreaded demo [1053:44225I am task 3, from thread: <NSThread: 0x600000064d00>{number = 1, name = main}
2019- 01- 23 10:02:43.511403+0800Multithreaded demo [1053:44225I am task 3, from thread: <NSThread: 0x600000064d00>{number = 1, name = main}
2019- 01- 23 10:02:43.511608+0800Multithreaded demo [1053:44225End]Copy the code

Asynchronous + serial queue

Features: New threads are opened and tasks are executed sequentially

  NSLog(Current thread %@[NSThread currentThread]);  // Prints the current thread
    NSLog(@ "start");
    dispatch_queue_t queue = dispatch_queue_create("testQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        // Append task 1
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(I am task 1, from thread: %@[NSThreadcurrentThread]); }});dispatch_async(queue, ^{
        // Append task 2
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(I am task 2, from thread: %@[NSThreadcurrentThread]); }});dispatch_async(queue, ^{
        // Add task 3
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog("I am task 3, from thread: %@"[NSThreadcurrentThread]); }});NSLog(@ "end");
Copy the code

Print result:

2019- 01- 23 10:09:26.140699+0800Multithreaded demo [1116:48819] current thread <NSThread: 0x600000076040>{number = 1, name = main}
2019- 01- 23 10:09:26.140906+0800Multithreaded demo [1116:48819] start2019- 01- 23 10:09:26.141049+0800Multithreaded demo [1116:48819End]2019- 01- 23 10:09:28.143936+0800Multithreaded demo [1116:48854I am task 1, from thread: <NSThread: 0x6000004629c0>{number = 3, name = (null)}
2019- 01- 23 10:09:30.148732+0800Multithreaded demo [1116:48854I am task 1, from thread: <NSThread: 0x6000004629c0>{number = 3, name = (null)}
2019- 01- 23 10:09:32.154261+0800Multithreaded demo [1116:48854I am task 2, from thread: <NSThread: 0x6000004629c0>{number = 3, name = (null)}
2019- 01- 23 10:09:34.156924+0800Multithreaded demo [1116:48854I am task 2, from thread: <NSThread: 0x6000004629c0>{number = 3, name = (null)}
2019- 01- 23 10:09:36.158106+0800Multithreaded demo [1116:48854I am task 3, from thread: <NSThread: 0x6000004629c0>{number = 3, name = (null)}
2019- 01- 23 10:09:38.162608+0800Multithreaded demo [1116:48854I am task 3, from thread: <NSThread: 0x6000004629c0>{number = 3, name = (null)}
Copy the code

Asynchronous + concurrent queue

Features: New threads are opened and tasks are executed alternately

    NSLog(Current thread %@[NSThread currentThread]);  // Prints the current thread
    NSLog(@ "start");
    
    dispatch_queue_t queue = dispatch_queue_create("testQueue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        // Append task 1
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(I am task 1, from thread: %@[NSThreadcurrentThread]); }});dispatch_async(queue, ^{
        // Append task 2
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];            
            NSLog(I am task 2, from thread: %@[NSThreadcurrentThread]); }});dispatch_async(queue, ^{
        // Add task 3
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog("I am task 3, from thread: %@"[NSThreadcurrentThread]); }});NSLog(@ "end");
Copy the code

Print result:

2019- 01- 23 10:15:29.424356+0800Multithreaded demo [1190:53683] current thread <NSThread: 0x604000074740>{number = 1, name = main}
2019- 01- 23 10:15:29.424575+0800Multithreaded demo [1190:53683] start2019- 01- 23 10:15:29.424723+0800Multithreaded demo [1190:53683End]2019- 01- 23 10:15:31.430195+0800Multithreaded demo [1190:53767I am task 3, from thread: <NSThread: 0x60400047f5c0>{number = 5, name = (null)}
2019- 01- 23 10:15:31.430195+0800Multithreaded demo [1190:53764I am task 2, from thread: <NSThread: 0x600000278a80>{number = 3, name = (null)}
2019- 01- 23 10:15:31.430195+0800Multithreaded demo [1190:53763I am task 1, from thread: <NSThread: 0x60400047fe40>{number = 4, name = (null)}
2019- 01- 23 10:15:33.435111+0800Multithreaded demo [1190:53763I am task 1, from thread: <NSThread: 0x60400047fe40>{number = 4, name = (null)}
2019- 01- 23 10:15:33.435111+0800Multithreaded demo [1190:53767I am task 3, from thread: <NSThread: 0x60400047f5c0>{number = 5, name = (null)}
2019- 01- 23 10:15:33.435111+0800Multithreaded demo [1190:53764I am task 2, from thread: <NSThread: 0x600000278a80>{number = 3, name = (null)}
Copy the code

V. Asynchronous + main queue (task execution is similar to synchronous + serial queue)

Features: The main queue is executed (tasks in the main queue are executed in the main queue) and tasks are executed in sequence

    NSLog(The current thread is: %@[NSThread currentThread]);  // Prints the current thread
    NSLog(@ "start");
    
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    dispatch_async(queue, ^{
        // Append task 1
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(I am task 1, from thread: %@[NSThreadcurrentThread]); }});dispatch_async(queue, ^{
        // Append task 2
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];              // Simulate time-consuming operations
            NSLog(I am task 2, from thread: %@[NSThread currentThread]);      // Prints the current thread}});dispatch_async(queue, ^{
        // Add task 3
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];              // Simulate time-consuming operations
            NSLog("I am task 3, from thread: %@"[NSThread currentThread]);      // Prints the current thread}});NSLog(@ "end");
Copy the code

Print result:

2019- 01- 23 10:19:33.503411+0800Multithreaded demo [1242:56892] Current thread is: <NSThread: 0x60000006eac0>{number = 1, name = main}
2019- 01- 23 10:19:33.503588+0800Multithreaded demo [1242:56892] start2019- 01- 23 10:19:33.503736+0800Multithreaded demo [1242:56892End]2019- 01- 23 10:19:35.538348+0800Multithreaded demo [1242:56892I am task 1, from thread: <NSThread: 0x60000006eac0>{number = 1, name = main}
2019- 01- 23 10:19:37.539726+0800Multithreaded demo [1242:56892I am task 1, from thread: <NSThread: 0x60000006eac0>{number = 1, name = main}
2019- 01- 23 10:19:39.541125+0800Multithreaded demo [1242:56892I am task 2, from thread: <NSThread: 0x60000006eac0>{number = 1, name = main}
2019- 01- 23 10:19:41.542511+0800Multithreaded demo [1242:56892I am task 2, from thread: <NSThread: 0x60000006eac0>{number = 1, name = main}
2019- 01- 23 10:19:43.543439+0800Multithreaded demo [1242:56892I am task 3, from thread: <NSThread: 0x60000006eac0>{number = 1, name = main}
2019- 01- 23 10:19:45.544663+0800Multithreaded demo [1242:56892I am task 3, from thread: <NSThread: 0x60000006eac0>{number = 1, name = main}
Copy the code

6. Synchronization + main queue

Features: Deadlocks caused by queues

- (void)syncMain {
    NSLog(Current thread: %@[NSThread currentThread]);  // Prints the current thread
    NSLog(@ "start");
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_sync(queue, ^{
        // Append task 1
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(I am task 1, from thread: %@[NSThreadcurrentThread]); }});dispatch_sync(queue, ^{
        // Append task 2
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(I am task 2, from thread: %@[NSThreadcurrentThread]); }});NSLog(@ "end");
}
Copy the code

Print result:

2019- 01- 23 10:25:00.640438+0800Multithreaded demo [1307:61022] current thread: <NSThread: 0x600000069a80>{number = 1, name = main}
2019- 01- 23 10:25:00.640607+0800Multithreaded demo [1307:61022] start (LLDB) crashCopy the code

Analysis: Since the main queue is a serial queue, we treat the syncMain method as a task and task 1 as a task. Both tasks are executed in the main queue. A primary queue is a special serial queue. The feature is that tasks are performed sequentially. So syncMain is executed first, and syncMain doesn’t finish until the task is finished. Task one waits for syncMain to finish. The two tasks wait for each other. Cause a deadlock. This is why synchronization is deadlocked on the primary queue and unlocked on the serial queue.