zoukankan      html  css  js  c++  java
  • iOS 多线程的简单理解(2) 队列 :串行 ,并行,MainQueue,GlobalQueue

    多线程队列是装载线程任务的队形结构。(系统以先进先出的方式调度队列中的任务执行 FIFO)。在GCD中有两种队列:

    串行队列、并发队列。

    队列 :串行队列、并发队列,全局主对列,全局并发队列

    2.1.  串行队列:线程只能依次有序的执行。

    2.1.1 串行方法 1

    - (void)SerialQueueOne{
         
        NSLog(@"串行1 start :::%@",[NSThread currentThread]);
        
        dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
        
        dispatch_sync(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"串行1   index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        dispatch_sync(queue, ^{
            for (int i = 10; i < 13; i++) {
                NSLog(@"串行1   index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        NSLog(@"串行1 end :::%@",[NSThread currentThread]);
    }
    

     执行结果:::

    2017-12-20 13:49:47.427330+0800 DeadThread[8972:2450330] 串行1 start :::<NSThread: 0x60800006ae80>{number = 1, name = main}
    2017-12-20 13:49:47.427470+0800 DeadThread[8972:2450330] 串行1   index 0 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
    2017-12-20 13:49:47.427567+0800 DeadThread[8972:2450330] 串行1   index 1 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
    2017-12-20 13:49:47.427636+0800 DeadThread[8972:2450330] 串行1   index 2 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
    2017-12-20 13:49:47.427696+0800 DeadThread[8972:2450330] 串行1   index 10 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
    2017-12-20 13:49:47.427819+0800 DeadThread[8972:2450330] 串行1   index 11 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
    2017-12-20 13:49:47.427893+0800 DeadThread[8972:2450330] 串行1   index 12 ::: <NSThread: 0x60800006ae80>{number = 1, name = main}
    2017-12-20 13:49:47.427966+0800 DeadThread[8972:2450330] 串行1 end :::<NSThread: 0x60800006ae80>{number = 1, name = main}
    

     得到结果:::

     1.代码顺序 执行;

    2.1.2 串行方法 2

    - (void)SerialQueueTwo{
        
        NSLog(@"串行2 start :::%@",[NSThread currentThread]);
        
        dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
        
       dispatch_async(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"串行2   index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        dispatch_async(queue, ^{
            for (int i = 10; i < 13; i++) {
                NSLog(@"串行2   index %d ::: %@",i,[NSThread currentThread]);
            }
        });
    
           NSLog(@"串行2 end :::%@",[NSThread currentThread]); 
    }
    

     执行结果:::

    2017-12-20 13:50:47.130380+0800 DeadThread[8993:2458517] 串行1 start :::<NSThread: 0x60c000071300>{number = 1, name = main}
    2017-12-20 13:50:47.130533+0800 DeadThread[8993:2458517] 串行1   index 0 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
    2017-12-20 13:50:47.130648+0800 DeadThread[8993:2458517] 串行1   index 1 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
    2017-12-20 13:50:47.130724+0800 DeadThread[8993:2458517] 串行1   index 2 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
    2017-12-20 13:50:47.130896+0800 DeadThread[8993:2458517] 串行1   index 10 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
    2017-12-20 13:50:47.130979+0800 DeadThread[8993:2458517] 串行1   index 11 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
    2017-12-20 13:50:47.131057+0800 DeadThread[8993:2458517] 串行1   index 12 ::: <NSThread: 0x60c000071300>{number = 1, name = main}
    2017-12-20 13:50:47.131130+0800 DeadThread[8993:2458517] 串行1 end :::<NSThread: 0x60c000071300>{number = 1, name = main}
    

     得到结果:::

    1.没有开启线程

    2.代码顺序执行;

    2.2 并发队列:线程可以同时一起进行执行。实际上是CPU在多条线程之间快速的切换。(并发功能只有在异步(dispatch_async)函数下才有效)

    2.2.1 并发方法 1

    - (void)concurrentQueueOne{
        
        NSLog(@"并发1 start :::%@",[NSThread currentThread]);
    
        dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    
        dispatch_sync(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"并发1  index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        dispatch_sync(queue, ^{
            for (int i = 10; i < 13; i++) {
                NSLog(@"并发1  index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        NSLog(@"并发1 end :::%@",[NSThread currentThread]);
    }
    

     执行结果:::

    2017-12-20 13:52:37.606997+0800 DeadThread[9023:2470506] 并发1 start :::<NSThread: 0x608000261600>{number = 1, name = main}
    2017-12-20 13:52:37.607130+0800 DeadThread[9023:2470506] 并发1  index 0 ::: <NSThread: 0x608000261600>{number = 1, name = main}
    2017-12-20 13:52:37.607197+0800 DeadThread[9023:2470506] 并发1  index 1 ::: <NSThread: 0x608000261600>{number = 1, name = main}
    2017-12-20 13:52:37.607447+0800 DeadThread[9023:2470506] 并发1  index 2 ::: <NSThread: 0x608000261600>{number = 1, name = main}
    2017-12-20 13:52:37.607685+0800 DeadThread[9023:2470506] 并发1  index 10 ::: <NSThread: 0x608000261600>{number = 1, name = main}
    2017-12-20 13:52:37.607891+0800 DeadThread[9023:2470506] 并发1  index 11 ::: <NSThread: 0x608000261600>{number = 1, name = main}
    2017-12-20 13:52:37.608056+0800 DeadThread[9023:2470506] 并发1  index 12 ::: <NSThread: 0x608000261600>{number = 1, name = main}
    2017-12-20 13:52:37.608190+0800 DeadThread[9023:2470506] 并发1 end :::<NSThread: 0x608000261600>{number = 1, name = main}
    

     得到结果:::

    1.线程顺序执行

    2.2.2 并发方法 2

    - (void)concurrentQueueTwo{
        
        NSLog(@"并发2 start :::%@",[NSThread currentThread]);
        
        dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
        
        dispatch_async(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"并发2  index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        dispatch_async(queue, ^{
            for (int i = 10; i < 13; i++) {
                NSLog(@"并发2  index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        NSLog(@"并发2 end :::%@",[NSThread currentThread]);
    }
    

     执行结果::;

    2017-12-20 13:56:45.573695+0800 DeadThread[9084:2492640] 并发2 start :::<NSThread: 0x604000077d80>{number = 1, name = main}
    2017-12-20 13:56:45.573891+0800 DeadThread[9084:2492640] 并发2 end :::<NSThread: 0x604000077d80>{number = 1, name = main}
    2017-12-20 13:56:45.573907+0800 DeadThread[9084:2492674] 并发2  index 0 ::: <NSThread: 0x60c000265a40>{number = 3, name = (null)}
    2017-12-20 13:56:45.573908+0800 DeadThread[9084:2492675] 并发2  index 10 ::: <NSThread: 0x60400026f000>{number = 4, name = (null)}
    2017-12-20 13:56:45.574283+0800 DeadThread[9084:2492674] 并发2  index 1 ::: <NSThread: 0x60c000265a40>{number = 3, name = (null)}
    2017-12-20 13:56:45.574344+0800 DeadThread[9084:2492675] 并发2  index 11 ::: <NSThread: 0x60400026f000>{number = 4, name = (null)}
    2017-12-20 13:56:45.574420+0800 DeadThread[9084:2492675] 并发2  index 12 ::: <NSThread: 0x60400026f000>{number = 4, name = (null)}
    2017-12-20 13:56:45.574422+0800 DeadThread[9084:2492674] 并发2  index 2 ::: <NSThread: 0x60c000265a40>{number = 3, name = (null)}
    

     得到结果:::

    1.添加两个 任务代码块,开启两个线程;

    2.子线程中代码 不是按顺序执行

    2.3 全局主队列::::

    2.3.1  主队列 同步 死锁

    - (void)syncMain {
     
        NSLog(@"
    
    **************主队列同步,放到主线程会死锁***************
    
    ");
     
        // 主队列
        dispatch_queue_t queue = dispatch_get_main_queue();
     
        dispatch_sync(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"主队列同步1   %@",[NSThread currentThread]);
            }
        });
        dispatch_sync(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"主队列同步2   %@",[NSThread currentThread]);
            }
        });
        dispatch_sync(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"主队列同步3   %@",[NSThread currentThread]);
            }
        });
    }
    

     死锁原因:::

        如果在主线程中运用主队列同步,也就是把任务放到了主线程的队列中。
    
        而同步对于任务是立刻执行的,那么当把第一个任务放进主队列时,它就会立马执行。
    
        可是主线程现在正在处理syncMain方法,任务需要等syncMain执行完才能执行。
    
        syncMain执行到第一个任务的时候,又要等第一个任务执行完才能往下执行第二个和第三个任务。
    
        这样syncMain方法和第一个任务就开始了互相等待,形成了死锁。
    

    2.3.2  主队列 异步

    - (void)asyncMain {
     
        NSLog(@"**************主队列异步***************");
     
        // 主队列
        dispatch_queue_t queue = dispatch_get_main_queue();
     
        dispatch_async(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"主队列异步1   %@",[NSThread currentThread]);
            }
        });
        dispatch_async(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"主队列异步2   %@",[NSThread currentThread]);
            }
        });
        dispatch_async(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"主队列异步3   %@",[NSThread currentThread]);
            }
        });
    }
    

     执行结果:::

    2017-12-20 14:20:01.729412+0800 DeadThread[9257:2636939] **************主队列异步***************
    2017-12-20 14:20:01.732208+0800 DeadThread[9257:2636939] 主队列异步1   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.732326+0800 DeadThread[9257:2636939] 主队列异步1   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.732456+0800 DeadThread[9257:2636939] 主队列异步1   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.732726+0800 DeadThread[9257:2636939] 主队列异步2   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.732931+0800 DeadThread[9257:2636939] 主队列异步2   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.733026+0800 DeadThread[9257:2636939] 主队列异步2   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.733128+0800 DeadThread[9257:2636939] 主队列异步3   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.733251+0800 DeadThread[9257:2636939] 主队列异步3   <NSThread: 0x604000261080>{number = 1, name = main}
    2017-12-20 14:20:01.733502+0800 DeadThread[9257:2636939] 主队列异步3   <NSThread: 0x604000261080>{number = 1, name = main}
    

    得到结果:::

    1. 主队列是个同步队列

    2.4 全局并发队列

    2.4.1

    - (void)globalQueueOne{
        
        NSLog(@"global1 start :::%@",[NSThread currentThread]);
        
        dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
        
        dispatch_sync(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"global1  index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        dispatch_sync(queue, ^{
            for (int i = 10; i < 13; i++) {
                NSLog(@"global1  index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        NSLog(@"global1 end :::%@",[NSThread currentThread]);
    }
    

     执行结果:::

    2017-12-20 14:27:02.302953+0800 DeadThread[9352:2669397] global1 start :::<NSThread: 0x6000000655c0>{number = 1, name = main}
    2017-12-20 14:27:02.303132+0800 DeadThread[9352:2669397] global1  index 0 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
    2017-12-20 14:27:02.303230+0800 DeadThread[9352:2669397] global1  index 1 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
    2017-12-20 14:27:02.303322+0800 DeadThread[9352:2669397] global1  index 2 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
    2017-12-20 14:27:02.303397+0800 DeadThread[9352:2669397] global1  index 10 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
    2017-12-20 14:27:02.303467+0800 DeadThread[9352:2669397] global1  index 11 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
    2017-12-20 14:27:02.303557+0800 DeadThread[9352:2669397] global1  index 12 ::: <NSThread: 0x6000000655c0>{number = 1, name = main}
    2017-12-20 14:27:02.303638+0800 DeadThread[9352:2669397] global1 end :::<NSThread: 0x6000000655c0>{number = 1, name = main}
    

    2.4.2

    - (void)globalQueueTwo{
        
        NSLog(@"global2 start :::%@",[NSThread currentThread]);
        
        dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
        
        dispatch_async(queue, ^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"global2   index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        dispatch_async(queue, ^{
            for (int i = 10; i < 13; i++) {
                NSLog(@"global2   index %d ::: %@",i,[NSThread currentThread]);
            }
        });
        
        NSLog(@"global2 end :::%@",[NSThread currentThread]);
    }
    

     执行结果:::

    2017-12-20 14:28:27.498062+0800 DeadThread[9382:2678820] global2 start :::<NSThread: 0x600000076700>{number = 1, name = main}
    2017-12-20 14:28:27.498208+0800 DeadThread[9382:2678820] global2 end :::<NSThread: 0x600000076700>{number = 1, name = main}
    2017-12-20 14:28:27.498250+0800 DeadThread[9382:2679707] global2   index 0 ::: <NSThread: 0x60c0000779c0>{number = 3, name = (null)}
    2017-12-20 14:28:27.498260+0800 DeadThread[9382:2679706] global2   index 10 ::: <NSThread: 0x60400007e800>{number = 4, name = (null)}
    2017-12-20 14:28:27.498555+0800 DeadThread[9382:2679707] global2   index 1 ::: <NSThread: 0x60c0000779c0>{number = 3, name = (null)}
    2017-12-20 14:28:27.498692+0800 DeadThread[9382:2679706] global2   index 11 ::: <NSThread: 0x60400007e800>{number = 4, name = (null)}
    2017-12-20 14:28:27.498710+0800 DeadThread[9382:2679707] global2   index 2 ::: <NSThread: 0x60c0000779c0>{number = 3, name = (null)}
    2017-12-20 14:28:27.498753+0800 DeadThread[9382:2679706] global2   index 12 ::: <NSThread: 0x60400007e800>{number = 4, name = (null)}
    
  • 相关阅读:
    octotree神器 For Github and GitLab 火狐插件
    实用篇如何使用github(本地、远程)满足基本需求
    PPA(Personal Package Archives)简介、兴起、使用
    Sourse Insight使用过程中的常使用功能简介
    Sourse Insight使用教程及常见的问题解决办法
    github 遇到Permanently added the RSA host key for IP address '192.30.252.128' to the list of known hosts问题解决
    二叉查找树的C语言实现(一)
    初识内核链表
    container_of 和 offsetof 宏详解
    用双向链表实现一个栈
  • 原文地址:https://www.cnblogs.com/Bob-blogs/p/8073578.html
Copyright © 2011-2022 走看看