1. Question answering

- (void)wbinterDemo{
    dispatch_queue_t queue = dispatch_queue_create("com.demo.test", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        NSLog(@"1");
    });
    dispatch_async(queue, ^{
        NSLog(@"2");
    });
    dispatch_sync(queue, ^{ NSLog(@"3"); });
    NSLog(@"0");
    dispatch_async(queue, ^{
        NSLog(@"Seven");
    });
    dispatch_async(queue, ^{
        NSLog(@"8");
    });
    dispatch_async(queue, ^{
        NSLog(@"9");
    });
    // A: 1230789
    // B: 1237890
    // C: 3120798
    // D: 2137890

}
Copy the code

The above code is printed in order A because the serial queue is the equivalent of turning asynchronous into synchronous execute dqF_width = 1 in order to guarantee the FIFO asynchronous function serial queue: start A new thread one task after another

- (void)wbinterDemo{
    dispatch_queue_t queue = dispatch_queue_create("com.demo.test", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        NSLog(@"1");
    });
    dispatch_async(queue, ^{
        NSLog(@"2");
    });
    dispatch_sync(queue, ^{ NSLog(@"3"); });
    NSLog(@"0");
    dispatch_async(queue, ^{
        NSLog(@"Seven");
    });
    dispatch_async(queue, ^{
        NSLog(@"8");
    });
    dispatch_async(queue, ^{
        NSLog(@"9");
    });
    // A: 1230789
    // B: 1237890
    // C: 3120798
    // D: 2137890

}
Copy the code

The answer is AC because synchronization blocks 3 must be before 0 123 unordered 789 unordered asynchronous function Concurrent queue: start a thread and execute tasks on the current thread asynchronously. Tasks execute asynchronously, in no order, depending on CPU scheduling

Main queue and global queue

Deadlock phenomenon

  • The main thread is waiting to execute the task first because you synchronize the function
  • The main queue waits for the main thread’s task to complete before executing its own task
  • The main queue and main thread waiting for each other can cause a deadlock

Synchronization function deadlock

The difference between synchronous and asynchronous functions

Can we create threads

Whether the callback of the task is asynchronous – synchronous

Libdispatch – 1271.120.2 source code

Synchronous serial deadlock underlying source analysis

To find thedispatch_syn To find the_dispatch_sync_f To find the_dispatch_sync_f_inline

Let’s take a look at _dispatch_barrier_sync_f

Find _dispatch_barrier_sync_f_inline

We ran a demo and found a deadlock

The last stack to execute the deadlock is first_dispatch_sync_f_slow

The last thing to do is __DISPATCH_WAIT_FOR_QUEUE__

So look at the _dispatch_barrier_sync_f_inline that we just looked at, and we should go _dispatch_sync_f_slow and look for that

Then look for __DISPATCH_WAIT_FOR_QUEUE__

Looking at the log inside is the same as the screenshot of our crash deadlock at the end of __DISPATCH_WAIT_FOR_QUEUE__ means that the deadlock is here and the queue that you called is held by the current thread

Let’s check the DSC -> dSC_waiter first

So let’s see that _dispatch_tid_self() is tid

Let’s take a look at _dq_state_drain_locked_BY

Let’s look at _dispatch_lock_is_locked_BY

When lock_value ^ tid = 0 & DLOCK_OWNER_MASK is equal to 0, lock_value = TID is equal to 0

dq_statedsc->dsc_waiterIt means that the two values are the same and the deadlock occurs and that’s the deadlock inquiry process

Synchronization function task synchronization

Synchronous global queue concurrency underlying source analysis

Let’s look at one detail first_dispatch_sync_invoke_and_completeThis method is passed infuncWhy is the first one written like this

Look at the DISPATCH_TRACE_ARG

Wrapping the comma here is optional

Is the concurrency going to be _dispatch_sync_F_slow or _dispatch_sync_RECURse and what we’re going to do is we’re going to use a demo to set these two system breakpoints and see what happens

Run it and see what happensAnd then I go to_dispatch_sync_function_invoke Then go_dispatch_sync_function_invoke_inline then_dispatch_client_calloutThe callback

This is the process of synchronizing a concurrent queue

Four. Asynchronous function analysis

Can we create threads

Function asynchrony

Asynchronous concurrent

Find dispatch_async

Enter the _dispatch_continuation_async

Enter the dx_push

Enter thedq_push

Enter the_dispatch_lane_concurrent_push

Enter the _dispatch_lane_push

Enter thedx_wakeup

Enter thedq_wakeup

Enter the_dispatch_lane_wakeup

Enter the _dispatch_lane_barrier_complete

Enter the _dispatch_lane_class_barrier_complete

Os_atomic_rmw_loop2o enters _dispatch_root_queue_push after the recursive execution

Enter the_dispatch_root_queue_push_inline

Enter the _dispatch_root_queue_poke

Enter the_dispatch_root_queue_poke_slow

Five. Singletons underlying principle

To be added

Six. Asynchronous function analysis

To be added