GCD Technology

Communication between the basic conceptual task and the creation of a queue queue


Basic concept

  • What is GCD? Full name is Grand Central Dispatch (translation is a great central scheduler) pure C language, provides a very powerful function
  • The advantage of GCD GCD is the Apple Corp for the multi-core parallel computing GCD solutions proposed will automatically use more CPU kernel (such as dual core, quad core) GCD will automatically manage the threads of the life cycle (create threads, thread scheduling, thread) programmers only need to tell GCD what you want to execute the task, do not need to write any thread management code

Tasks and queues

  • There are two core tasks in GCD: what is the implementation of the queue: used to store tasks
  • The use of GCD 2 steps: determining the custom task to do the task will be added to the queue: GCD will automatically be in the job queue out, on the implementation of the corresponding task thread out follow the queue FIFO principle: FIFO, LIFO
  • Perform tasks perform tasks using synchronous dispatch_sync
    mode (dispatch_queue_t queue, dispatch_block_t block;
    dispatch_async) mission with asynchronous mode
    queue:
    block: (dispatch_queue_t Queue task queue, dispatch_block_t block);
  • Synchronous and asynchronous synchronization: synchronization can only be performed in the current thread, do not have the ability to open a new thread asynchronous: you can perform tasks in the new thread, with the ability to open a new thread
  • The type of concurrent queues (Concurrent Dispatch Queue) allows multiple concurrent tasks (simultaneously), automatically open multiple threads simultaneously perform concurrent tasks function only in asynchronous function (dispatch_async) is effective serial (Serial Dispatch Queue) to queue tasks one by one execution (that is a must a task can be executed only after the completion of the execution of the next task)
  • Confusing terms in the development of
    , we can easily confuse synchronous and asynchronous, concurrent, serial, following it again I emphasize that the difference between synchronous and asynchronous main effects: can open a new thread synchronization: just to perform tasks in the current thread, does not have the ability to open a new asynchronous thread that can perform tasks in a new thread, have mainly affect the ability to open a new thread concurrent and serial concurrent task execution: (must be used to achieve asynchronous concurrency) allows multiple concurrent tasks (the same time): a serial execution task is completed, then the execution of a task

According to the impact point


Queue creation

  • Parallel queue GCD provides two ways to get parallel queue using the dispatch_queu_create function to create a
    dispatch_queue_create (const char *label, dispatch_queue_attr_t attr);
    label said:
    att said: the name of the queue queue type, according to this judgment is set parallel or serial queue queue (DISPATCH_QUEUE_CONCURRENT parallel queue) concurrent queue using the dispatch_get_global_queue function global (this is provided by GCD (dispatch_get_global_queue) dispatch_queue_prority_t priority, unsigned long flags;
    priority): queue priority (high, low background, by default,
    flag): this parameter can be used temporarily useless, 0
  • Serial queue GCD provides two ways to obtain serial queue uses the dispatch_queue_create function to create the serial dispatch_queue_create (const char *label
    queue, dispatch_queue_attr_t attr);
    label said: the queue name (ID) of
    attr said: the queue properties, according to this judgment is set parallel or serial queue queue (DISPATCH_QUEUE_SERIAL or NULL serial use the column (queue) associated with the main thread of the queue) column is a kind of special serial queue with GCD placed into the list of tasks will be performed using dispatch_get_main_queue in the main thread () for the column

Engineering template: CGD queue


- (void) touchBegan: (NSSet * touches) withEvent: (UIEvent * event) {//[self concurrentSync]; //[self concurrentAsync]; //[self globalSync]; //[self globalAsync]; //[self mainSync]; //[self serialSync] #pragma} / / deadlock; Mark - Concurrent queue + synchronous task: did not start a new thread, the task is executed one by one - (void) concurrentSync {/ / create concurrent queue dispatch_queue_t queue= dispatch_queue_create (myQueue, DISPATCH_QUEUE_CONCURRENT); / / add / / in the task queue synchronization task dispatch_sync (queue, for ^{(int i = 0; i< 5; i++) {NSLog (@ "===1===%@", [NSThread currentThread]);}} (queue, dispatch_sync); ^{for (int i = 0; i< 5; i++) {NS Log (@ "===2===%@", [NSThread currentThread]);}}); dispatch_sync (queue, for ^{(int i = 0; i< 5; i++) {NSLog (@ "===3===%@", [NSThread currentThread]);}}}); #pragma - mark + asynchronous concurrent Queue task (void) {concurrentAsync dispatch_queue_t queue= dispatch_queue_create / / create concurrent queue (Queue, DISPATCH_QUEUE_CONCURRENT); / / asynchronous task dispatch_async (queue, for ^{(int i = 0; i< 5; i++) {NSLog (@ "===1===%@" [NSThread, currentThread]);}}); dispatch_async (queue, for ^{(int i = 0; i< 5; i++) {NSLog (@ "===2===%@", [NSThread currentThread]);}}); dispatch_async (queue, for int i (^{ = 0; i< 5; i++) {NSLog (@ "===3===%@", [NSThread currentThread]);}}}); #pragma + mark - global queue synchronization tasks: did not start a new thread, the task is executed one by one - (void globalSync) {/ / create a global queue of dispatch_queue_t queue= dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) dispatch_sync; / / synchronization tasks (queue, for ^{(int i = 0; i< 5; i++) {NSLog (@ "===1===%@", [NSThread currentThread]);}}); dispatch_sync (queue, for ^{(int i = 0; i< 5; i++) {NSLog (@ "===2===%@". [NSThread currentThread]);}}); dispatch_sync (queue, for ^{(int i = 0; i< 5; i++) {NSLog (@ "===3===%@", [NSTh Read currentThread]);}}}); #pragma + mark - global queue asynchronous task: open a new thread, the task is executed concurrently - (void globalAsync) {/ / create a global queue of dispatch_queue_t queue= dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); / / asynchronous task dispatch_async (queue, for ^{(int i = 0; i< 5; i++) {NSLog (@ "===1===%@", [NSThread currentThread]);}}); dispatch_async (queue, for ^{(int i = 0; i< 5; i++) {NSLog (@ "===2===%@", [NSThread currentThread]);}}); dispatch_async (queue, for int I (^{= 0; i< 5; i++) {NSLog (@ "===3===%@", [NSThread currentThread]);}}}); #warning - death Lock #pragma mark - home team + sync task: card dead!!! Deadlock - (void) mainSync dispatch_queue_t queue {/ / create the column (= dispatch_get_main_queue); / / synchronous task dispatch_sync (queue, for ^{(int i = 0; i< 5; i++) {NSLog (@ "===1===%@", [NSThread currentThread]);}}); dispatch_sync (queue, for int i (^{= 0; i< 5; i++) {NSLog (@ "===2===%@", [NSThread currentThread]);}}); dispatch_sync (queue, for ^{(int i = 0; i< 5; i++) {NSLog (@ "===3===%@", [NSThread currentThread]);}}}); #pragma - mark home column + asynchronous queue: no open a new thread, task is accomplished - (void) serialSync dispatch_queue_t queue {/ / create the column (= dispatch_queue_create "Queue", NULL); / / asynchronous task dispatch_async (queue, for ^{(int i = 0; i< 5; i++) {NSLog (@ "===1===%@", [NSThread currentThread]);}}); dispatch_async (queue, for ^{(int i = 0; i< 5; i++) {NSLog (@ "===2===%@", [NSThread currentThread]);}}); dispatch_async (queue, for ^{(int i = 0; i< 5; i++) {NSLog (@ "===3===%@", [NSThread currentThread]);}}});

Communication between threads

Communication between threads mark - #pragma - downloadImage (void) {dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{/ / NSURL *url = [NSURL URLWithString:@ time-consuming operation ""]; NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:data]; / / return to the main thread (dispatch_get_main_queue), dispatch_async (^{/ display picture; UIImageView *imageView [[UIImageView = alloc]init]; imageView.image = image;});}});

Other uses

  • IOS common delay execution there are 2 ways to call the NSObject
    [self perform selector:@selector (run) withObject:nil afterDelay:2.0] dispatch_after; using the GCD function (dispatch_time (DISPATCH_TIME_NOW (int64_t) (2.0* NSEC_PER_SEC)), dispatch_get_main_queue (//2), ^{seconds after the asynchronous execution of the code here…});
  • A one-time code uses the dispatch_once function to ensure that a section of code in the program is executed only 1 times static dispatch_once_t onceToken; dispatch_once (& onceToken, ^{/ / only performed 1 times the code (which is the default thread safe)});
  • Queue group
    there are 1 types of
    : first demand asynchronous execution 2 time consuming operation
    second: 2 asynchronous operation after the completion of the execution, and then return to the main thread to execute operation
    if you want to realize the above requirements, consider using dispatch_group_t group = dispatch_group_create (cohort dispatch_group_async (group, dispatch_get_global_queue); (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{/ / 1 time asynchronous operation (group, dispatch_group_async);} dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{/ / 1 time asynchronous operation}); dispatch_group_notify (Group), dispatch_get_main_queue (asynchronous operation ^{/ / etc. in front of all after the execution is completed, go back to the main thread})..;

- (void) touchBegan: (NSSet * touches) withEvent: (UIEvent * event) {//[self delay]; //[self once]; //[self group];} #pragma mark - (void) delay delay operation - {//NSObject //[self performSelector:@selector (run) withObject:nil afterDelay:2.0] //NSTimer //[NSTimer scheduledTimerWithTimeInterval:2.0 target:self; selector:@selector (run) userInfo:nil repeats:NO] dispatch_after (dispatch_time (DISPATCH_TIME_NOW; //GCD (int64_t) (*NSEC_PER_SEC, 2)), dispatch_get_main_queue ([self), ^{); run];}} - {(void) run NSLog (@ run);} #pragma mark - an operation - (void) once dispatch_once_t onceToken {static; dispatch_once (& onceToken, ^{(@ NSLog disposable ");}}); #pragma mark Multiple - operation - (void) apply {dispatch_apply (10, dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ (size_t index) {NSLog (@ "===%ld===", index);}}); #pragma mark (void) group cohort - {/ / create a group dispatch_group_t group = dispatch_group_create (dispatch_group_async (Group); dispatch_get_global_queue, (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{for (int i = 0; i< 5; i++) {NSLog (@ ===1===);}}); dispatch_group_async (group, dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{for (int i = 0; i< 5; i++) {NSLog (@ the "===1===");}}); / / 1 2, when completed, to the implementation of the 3 dispatch_group_notify (group, dispatch_ Get_main_queue (NSLog), ^{(@ ===3===);}});