preface

Last time we ran the use of GCD functions and saw deadlocks through the understanding of serial queues and concurrent queues. This time we look at the relationship between GCD functions and queues

I. Main queue analysis

Queues are divided into serial queues and parallel queues

  1. Serial queue:dispatch_queue_t serial = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
  2. Concurrent queue:dispatch_queue_t conque = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
  3. The home side columns:dispatch_queue_t mainQueue = dispatch_get_main_queue();
  4. Global queue:dispatch_queue_t globQueue =dispatch_get_global_queue(0, 0);

Find libDispatch-1271.120.2 through BT print source analysis GCD

Search dispatch_get_main_queue through the libDispatch source code

_dispatch_main_q

Find the name by printing the main queue

Search globally for com.apple.main-thread

Dq_atomic_flags = DQF_WIDTH(1),.dq_serialNum = 1, so it is a serial queue

Serial and concurrent underlying source identification

Both serial and parallel queues are created using dispatch_queue_CREATE. Let’s examine the source code below

Enter the _dispatch_lane_create_with_target

Dqai_concurrent? Is passed through the _dispatch_queue_init function. DISPATCH_QUEUE_WIDTH_MAX: 1 Go to dispatch_queue_init and let’s see

So DQF_WIDTH =1 is a serial queue and it has nothing to do with dq_serialNum =1

dq_serialnum =os_atomic_inc_orig(&_dispatch_queue_serial_numbers, relaxed)

So what’s dispatch_queue_serial_numbers

What’s DISPATCH_QUEUE_SERIAL_NUMBER_INIT

The following method does the prioritization

Serial queuingNULLThe reason is whendqaiforNULLDirectly return whendqai

Three.GCD underlying source inheritance chain

Print com.apple.root.default-qos through BT

Search com.apple.root.default-qos through libDispatch source code

Dispatch_queue_t and I’ll go in

DISPATCH_DECL corresponds in the source code

#define DISPATCH_DECL(name) \
typedef struct name##_s : public dispatch_object_s {} *name##_t
Copy the code

DISPATCH_DECL(dispatch_queue);

typedef struct dispatch_queue_s : public dispatch_object_s {} *dispatch_queue_t

Equivalent to dispatch_queue_t-> dispatch_queue_S ->dispatch_object_s-> _OS_OBJect_s ->dispatch_object_t class->objc_object

All of themdispatch_object_tThis type of

Four.MT and KS interview questions

- (void)MTDemo{

    while(self.num < 5) {

        dispatch_async(dispatch_get_global_queue(0.0), ^{

            self.num++;

        });

    }
    NSLog(@"end : %d",self.num); / / > = 5 results
}
Copy the code
- (void)KSDemo{

   

    for(int i= 0; i<10000; i++) {

        dispatch_async(dispatch_get_global_queue(0.0), ^{

            self.num++;

        });

    }

    NSLog(@"end : %d",self.num); / / < = 10000

}
Copy the code

5.GCD’s task execution Stack (synchronization)

Where is the block() of dispatch_sync called

What is _dispatch_Block_invoke

Let’s look at _dispatch_sync_f

Look at the_dispatch_sync_f_inline

Add a symbolic breakpoint _dispatch_sync_f_slow discovery comes in

Add a symbol breakpoint _dispatch_sync_function_invoke found entered

Look at the_dispatch_sync_function_invoke_inline Look at the_dispatch_client_callout

The breakpointbtVerify that the exploration process is working

Vi.GCD’s task execution stack (asynchronous)

Where is the block() of dispatch_async called

Look at the_dispatch_continuation_init

Look at _dispatch_continuation_init_f

Check that the value of _dispatch_continuation_priority_set is asynchronously processed

Look at the_dispatch_continuation_async

Look at thedx_push

Look at the Dq_push queue_global queue

Look at _dispatch_root_queue_push

Check out _dispatch_root_queue_push_inline

Look at the_dispatch_root_queue_poke

Look at the_dispatch_root_queue_poke_slow

Look at _dispatch_root_queues_init

Take a look at _dispatch_root_queues_init_once

Take a look at _dispatch_worker_thread2

Take a look at _dispatch_root_queue_drain

Check _dispatch_continuation_POP_inline

Check out _dispatch_continuation_invoke_inline

Take a look at _dispatch_client_callout

Take a look at DX_Invoke

Take a look at do_invoke

Take a look at _dispatch_queue_override_invoke

Check out _dispatch_continuation_invoke_inline

Take a look at _dispatch_client_callout

Bt print