Multithreading (iii) GCD

Source: Internet
Author: User
Tags gcd

First, GCD
    • Gcd:grand Central Dispatch, Grand centralized dispatch!!! Is the solution that Apple proposes for multi-core parallel operation, it will automatically make use of more CPU cores (such as dual core, quad core), the bottom of GCD is still implemented by thread, but it will automatically manage the thread's life cycle (create thread, dispatch task, destroy thread), do not need our management at all. We just have to tell them what to do. It also uses the C language, but the use of blocks (called closures in swift) makes it easier and more flexible to use.
Two concepts of GCD: Tasks and queues
    • Task: That is, the operation, is a piece of code, in the GCD is a Block. There are two ways to perform a task: synchronous execution and asynchronous execution, the difference between them: whether a new thread will be created.
      • Synchronous execution: Whenever a task is performed synchronously, it will be executed on the current thread and will not be threaded separately.
      • Asynchronous execution: Whenever a task is executed asynchronously, it will be executed on another thread.
    • Update:
The main difference between synchronous and asynchronous (async) is whether the current thread will be blocked until the task in the block is executed!        The sync operation blocks the current thread and waits for the task in the block to complete before the current thread continues to run down. Asynchronous (Async) operation, the current thread executes directly down, and it does not block the current thread.
    • Queue: Used to hold tasks. A total of two kinds of queues,
      • Serial queue: The tasks in the serial queue are executed according to the execution of the queue's definition FIFO, one by one, first in and out.
      • Parallel queues: Tasks in a parallel queue have different execution modes depending on the synchronization or async.
        • In the serial queue task, the GCD will also be taken out of the FIFO, but the difference is that it takes out one of the other threads and then pulls out another thread. As a result of taking the action quickly, negligible, it seems that all the tasks are executed together. However, it is important to note that GCD will control the number of parallelism based on system resources, so if there are many tasks, it will not allow all tasks to execute concurrently.
Third, create a queue
  • Main queue: This is a special serial queue. It is used to refresh the UI, and any work that needs to refresh the UI is performed in the main queue, so the usual time-consuming tasks are put on to other threads to execute.
    • dispatch_queue_t queue = Dispatch_get_main_queue ();
  • queues that you create yourself: You can create a serial queue, or you can create a parallel queue.
    • It has two parameters, the first parameter is the identifier, which is used when debugging to identify a unique queue and can be empty.
    • The second is the most important, which indicates whether the created queue is serial or parallel, and
      • passing in dispatch_queue_serial or NULL means creating a serial queue, which is typically used to synchronize access to specific resources or data. When you create multiple serial queues, the serial queue is executed concurrently with the serial queue, although they are executed synchronously. The
      • incoming dispatch_queue_concurrent represents the creation of a parallel queue that can perform multiple tasks concurrently, but the order in which the execution is completed is random.
    • dispatch_queue_t queue = dispatch_queue_create ( ) Tk.bourne.testQueue " ,  null);
  • Global Parallel queue: This should be the only parallel queue, as long as parallel tasks are generally added to this queue.
    • dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    • Priority (first parameter):
      • #define DISPATCH_QUEUE_PRIORITY_HIGH 2//highest priority, executed before default, and low
        #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0//default priority, before low, after high
        #define Dispatch_queue_priority_low (-2)//After high and default execution
        #define DISPATCH_QUEUE_PRIORITY_BACKGROUND Int16_min The   // task submitted to this queue is executed after the high priority task and the execution has been committed to the BACKGROUND queue.
Iv. Creation of tasks
  • Sync task: No other thread (sync)
    •  dispatch_sync(, ^{      //code here      NSLog(@"%@", [NSThread currentThread]);  });
  • Asynchronous task: Another thread (async)
    •   dispatch_async (,  ^{         //code here        NSLog (@ "%@" ,  [nsthread currentthread]);    });
  • Example one:
    • -(void) gcdtest{
      NSLog (@ "Before-%@", nsthread.currentthread);
      Dispatch_sync (Dispatch_get_main_queue (), ^{
      NSLog (@ "Sync-%@", nsthread.currentthread);
      });
      NSLog (@ "After-%@", nsthread.currentthread);
      }
    • Only the first sentence is printed: before-{number = 1, name = main}, then the main thread dies.
    • Cause: The synchronization task blocks the current thread, and then puts the task in the block into the specified queue, only to wait until the task in the block has completed before the current thread continues to run down.
    • After printing the first sentence, Dispatch_sync immediately block the current main thread, and then put the task in the block into the Main_queue, you can main_queue in the task will be removed to put in the main thread to execute, but the main thread this time has been blocked, so block In the task can not be completed, it is not completed, Dispatch_sync will always block the main thread, this is the deadlock phenomenon. Causes the main thread to remain stuck.
  • Example two:
    • -(void) GcdTe1 {
      dispatch_queue_t queue = dispatch_queue_create ("Myqueue", dispatch_queue_serial);
      NSLog (@ "before 1-%@", nsthread.currentthread);
      Dispatch_async (Queue, ^{
      NSLog (@ "2 before synchronization-%@", nsthread.currentthread);
      Dispatch_sync (Queue, ^{
      NSLog (@ "3 sync-%@", nsthread.currentthread);
      });
      NSLog (@ "4 after synchronization-%@", nsthread.currentthread);
      });
      NSLog (@ "5 after-%@", nsthread.currentthread);
      }
    • 1,2,5 will print, 3,4 will not
    • Dispatch_async executes asynchronously, the current thread is not blocked, so there are two threads, one current thread continues to print 1, and the other executes the contents of block print 2. Because these two lines are parallel, the order of printing is irrelevant.
      Dispatch_sync is executed synchronously, the thread that it is in is blocked and will continue until the task in sync is executed. Sync then puts the task in the block into the queue, but the queue is a serial queue and performs one task at a time, so the block of sync must wait until the previous task is completed, but the queue is performing the task that is blocked by sync. So there was a deadlock. So the thread where sync is stuck is dead.
  • Queue Group
    • Many queues can be added to a group, and when all the tasks in the group are executed, the queue group notifies us through the Dispatch_group_notify method.
    • Example:
      • -(void) group1 {
        dispatch_group_t group = Dispatch_group_create ();
        dispatch_queue_t queue = Dispatch_get_global_queue (Dispatch_queue_priority_default, 0);
        Multiple ways to use queue groups to perform tasks, only async methods
        Dispatch_group_async (group, queue, ^{
        for (Nsinteger i = 0; i < 3; i++) {
        NSLog (@ "group-01-%@", [Nsthread CurrentThread]);
        }
        });

        Dispatch_group_async (Group, Dispatch_get_main_queue (), ^{
        for (Nsinteger i = 0; i < 8; i++) {
        NSLog (@ "group-02-%@", [Nsthread CurrentThread]);
        }
        });

        Dispatch_group_async (group, queue, ^{
        for (Nsinteger i = 0; i < 5; i++) {
        NSLog (@ "group-03-%@", [Nsthread CurrentThread]);
        }
        });
        will automatically notify you when you are done.
        Dispatch_group_notify (Group, Dispatch_get_main_queue (), ^{
        NSLog (@ "Finish-%@", [Nsthread CurrentThread]);
        });
        }

Five, single-case mode
    • @interface Tool:nsobject
      + (instancetype) Sharedtool;
      @end
      @implementation Tool
      Static ID _instance;
      + (Instancetype) Sharedtool {
      Static dispatch_once_t Oncetoken;
      Dispatch_once (&oncetoken, ^{
      _instance = [[Tool alloc] init];
      });
      return _instance;
      }
      @end
Vi. Other uses
  • Barrier
  • Dispatch_barrier_async is executed after the execution of the previous task is completed, and the task after it is executed before it executes.
    • This approach focuses on your incoming queue, which blocks the queue when you pass in a queue that is created by the dispatch_queue_concurrent parameter itself (note that blocking the queue instead of blocking the current thread) Wait until the task in front of it in the queue has been completed before it starts executing itself, and after executing it, it cancels the blocking so that the task that follows it in the queue continues to execute.
    • If you pass in another queue, it's just like Dispatch_async.
    • Example:
      • -(void) Gcdbarrier {
        dispatch_queue_t queue = dispatch_queue_create ("GCDTEST.WWL", dispatch_queue_concurrent);
        Dispatch_async (Queue, ^{
        [Nsthread Sleepfortimeinterval:2];
        NSLog (@ "---> 1");
        });
        Dispatch_async (Queue, ^{
        [Nsthread Sleepfortimeinterval:4];
        NSLog (@ "---> 2");
        });
        Dispatch_barrier_async (Queue, ^{
        NSLog (@ "---> 3");
        [Nsthread Sleepfortimeinterval:4];

        });
        Dispatch_async (Queue, ^{
        [Nsthread sleepfortimeinterval:1];
        NSLog (@ "---> 4");
        });
        }
      • Note the print time
      • 2016-03-23 13:38:15.526 05-gcd the Use [8252:2162446]---> 1
        Use of 2016-03-23 13:38:17.526 05-gcd
        [8252:2162447]---> 2
        Use of 2016-03-23 13:38:17.527 05-gcd
        [8252:2162447]---> 3
        Use of 2016-03-23 13:38:22.539 05-gcd
        [8252:2162447]---> 4
  • Dispatch_barrier_sync
    • This method uses the same as the previous one, passing in a custom concurrency queue (dispatch_queue_concurrent), which blocks the queue like the previous method, but this method also blocks the current thread.
    • If you pass in another queue, it will be the same as Dispatch_sync.
  • Execute a piece of code N times
  • Dispatch_apply (size_t iterations, dispatch_queue_t queue, ^ (size_t) {//code});
    • size_t iterations: Number of code executions
    • dispatch_queue_t Queue: Incoming queues
    • size_t: The current number of executions of the Code,
  • Example:
    • -(void) gcdapply {
          dispatch_apply (5, dispatch_get_global_queue (0, dispatch_queue_priority _default), ^ (size_t index) {
               NSLog (@ "---->%ld %@", index, [Nsthread current Thread]);
         });
      }
    • 2016-03-23 14:07:04.789 05-gcd the Use [8302:2166524]----> 0 <nsthread:0x16669b20>{number = 1, name = main}
      2016-03-23 14:07:04.789 05-gcd
      use [8302:2166540]----> 1 <nsthread:0x16587ed0>{number = 2, n AME = (NULL)}
      2016-03-23 14:07:04.792 05-gcd
      use [8302:2166540]----> 3 <nsthread:0x16587ed0>{number = 2, n AME = (NULL)}
      2016-03-23 14:07:04.793 05-gcd
      use [8302:2166540]----> 4 <nsthread:0x16587ed0>{number = 2, n AME = (NULL)}
      2016-03-23 14:07:04.793 05-gcd
      use [8302:2166524]----> 2 <nsthread:0x16669b20>{number = 1, name = main}
    • Because the incoming is a global queue, is parallel, so will be the thread, the order of printing is uncertain.
    • The serial queue will be printed sequentially, without thread
    • dispatch_queue_t queue = dispatch_queue_create ("GCDTEST.WWL", dispatch_queue_serial);
      Dispatch_apply (5, queue, ^ (size_t index) {
      NSLog (@ "---->%ld%@", Index,[nsthread CurrentThread]);
      });
  • Back to the main thread from other threads
    • Dispatch_async (Dispatch_get_main_queue (), ^{
      Note that it is asynchronous
      });
  • Download Image examples:
    • -(void) Downloadimages {
      dispatch_queue_t queue = Dispatch_get_global_queue (Dispatch_queue_priority_default, 0);

      Download Images asynchronously
      Dispatch_async (Queue, ^{
      Creating a group
      dispatch_group_t group = Dispatch_group_create ();

      __blockuiimage *image1 = nil;
      __blockuiimage *image2 = nil;

      Associating a task to a group
      Dispatch_group_async (Group, Dispatch_get_global_queue (Dispatch_queue_priority_default, 0), ^{
      Download the first picture
      NSString *URL1 = @ "Http://car0.autoimg.cn/upload/spec/9579/u_20120110174805627264.jpg";
      Image1 = [SELFIMAGEWITHURLSTRING:URL1];
      });

      Associating a task to a group
      Dispatch_group_async (Group, Dispatch_get_global_queue (Dispatch_queue_priority_default, 0), ^{
      Download the first picture
      NSString *url2 = @ "Http://hiphotos.baidu.com/lvpics/pic/item/3a86813d1fa41768bba16746.jpg";
      Image2 = [SELFIMAGEWITHURLSTRING:URL2];
      });

      Wait for the task in the group to complete, return to the main thread to execute block callback
      Dispatch_group_notify (Group, Dispatch_get_main_queue (), ^{
      Self.imageView1.image = Image1;
      Self.imageView2.image = Image2;
      });
      });
      }

      -(UIImage *) imagewithurlstring: (NSString *) urlstring {
      Nsurl *url = [nsurlurlwithstring:urlstring];
      NSData *data = [Nsdatadatawithcontentsofurl:url];
      return [[Uiimagealloc] initwithdata:data];
      }
    • Reference Blog
      • http://blog.csdn.net/q199109106q/article/details/8566300
      • Http://www.cocoachina.com/ios/20150731/12819.html
      • http://blog.csdn.net/hello_hwc/article/details/41204027
      • http://blog.jobbole.com/69019/
      • Http://blog.csdn.net/column/details/swift-gcd.html

Multithreading (iii) GCD

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.