美文网首页
iOS开发随性总结之多线程

iOS开发随性总结之多线程

作者: sooooooooEasy | 来源:发表于2016-07-21 21:23 被阅读43次

    什么是多线程?

    要知道什么是多线程首先要了解进程和线程的概念。

    进程:

    指系统中正在运行的应用程序,而且每个进程之间是相互独立的

    线程:

    程序执行的基本单元,程序中的任务都在线程中执行
    线程中执行任务的方式分为串行和并行,串行指所有任务按照顺序依次执行,并行是指在一个线程中多个任务同时执行

    多线程:

    在一个进程中可以开辟多个线程来同时(并行)运行,每个线程也可串行或并行执行任务。但是CPU同一时间只能处理一条线程,多线程并发执行其实是由于CPU运行速度足够快,在多条线程之间进行调度,造成了多条线程并发执行的假象,如果有非常多的线程同时执行,也许会造成CPU崩溃
    多线程的优缺点:

    多线程的优缺点

    优点:

    ①能适当提高程序的执行效率
    ②能适当提高资源利用率(CPU、内存利用率)

    缺点:

    ①开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能
    ②线程越多,CPU在调度线程上的开销就越大
    ③程序设计更加复杂:比如线程之间的通信、多线程的数据共享

    iOS里面实现多线程的方案:

    #######iOS中目前多线程有4套实现方案:

    Pthread:

    这是一套在很多操作系统上都通用的多线程API,移植性很强。不过这是基于c语言的框架,使用起来有点困难,对程序猿的技术要求略高

    NSThread:

    是相对轻量级的,但也是使用起来最负责的,你需要自己管理thread的生命周期,线程之间的同步。线程共享同一应用程序的部分内存空间,它们拥有对数据相同的访问权限。

    GCD:

    Grand Central Dispatch (GCD)是Apple开发的一个多核编程的较新的解决方法。GCD是一个替代诸如NSThread等技术的很高效和强大的技术。GCD完全可以处理诸如数据锁定和资源泄漏等复杂的异步编程问题。GCD的工作原理是让一个程序,根据可用的处理资源,安排他们在任何可用的处理器核心上平行排队执行特定的任务。这个任务可以是一个功能或者一个程序段。这是iOS开发中最多使用的多线程实现方案

    NSOperation:

    NSOperation实际上是苹果对GCD的封装,相对于GCD来说可控性更高,NSOperation实际上是一个抽象的基类,并不能直接使用,需要通过继承于它的子类来调用各种方法实现功能

    简单实现

    pthread:

    首先当然是导入头文件
    <pre><code>

    import "pThread"

    </code></pre>

    假设我们有一耗时操作(写成函数指针形式)

    void *run(void *costTime) {
      for (NSInteger i = 0; i < 10000; i++) {   
        NSLog(@"%ld", i)
      }   
    }
    

    这里我是设置一个Button的点击事件来执行

    - (void)btnClick {
      pthread_t pThread;
      pthread_create(&pthread, NULL, run, NULL);
      // 第一个参数:线程指针
      // 第二个参数:线程的一些属性    
      // 第三个参数:用于执行方法的函数指针
      // 第四个参数:线程中的传值
    }
    

    这样就创建了一条线程来执行函数costTime,主线程的任务可以继续执行,不必等待

    NSThread:

    - (void)creadNSThread
    {
        // 创建线程
        NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(costTime) object:@"111"];
        thread.name = @"222";
        
        // 开启线程
        [thread start];
        NSLog(@"%@", [NSThread currentThread]);//当前线程
        NSLog(@"%@", [NSThread mainThread]);//主线程
        NSLog(@"%d", [NSThread isMainThread]);//是否为主线程
    }
    
    // 快捷创建方式
    - (void)creatNSThread1
    {
        // 快捷创建 无返回值
        [NSThread detachNewThreadSelector:@selector(costTime) toTarget:self withObject:nil];
    }
    

    NSOperation:

    - (void)createNSOperation
    {
        NSInvocationOperation *operation_1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationAction1) object:nil];
        NSInvocationOperation *operation_2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationAction2) object:nil];
        // block方式创建多线程
        NSBlockOperation *operation_3 = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"第三个 -- %d", [NSThread isMainThread]);
            for (int i = 0; i < 1000; i++) {
                NSLog(@"第三个 -- %d", i);
            }
        }];
        
        // 操作队列
        // 目的:将任务放在一个队列中执行
        // 任务:任务执行在主线程还是在子线程全部都是由我们的队列来决定的
        // 获取主队列
    //    NSOperationQueue *queue = [NSOperationQueue mainQueue];
        // alloc init 的代表字其他队列
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        // 先加入队列的先执行,但是执行的时间不定,可能后执行的比先执行的先执行完
        [queue addOperation:operation_1];
        [queue addOperation:operation_2];
        [queue addOperation:operation_3];
        
    }   
    
    - (void)operationAction1
    {
        NSLog(@"第一个 -- %d", [NSThread isMainThread]);
        for (int i = 0; i < 1000; i++) {
            NSLog(@"第一个 -- %d", i);
        }
    }
    
    - (void)operationAction2
    {
        NSLog(@"第二个 -- %d", [NSThread isMainThread]);
        for (int i = 0; i < 1000; i++) {
            NSLog(@"第二个 -- %d", i);
        }
    }
    

    GCD:

    - (void)viewDidLoad {
        [super viewDidLoad];
    // 下面这种方式中,最内层的任务永远不会执行,因为任务2要等待任务执行完才会执行,而任务2又在任务1中,造成类似死循环
    // 所以这里是一个错误演示
        dispatch_queue_t queue = dispatch_queue_create("sss", DISPATCH_QUEUE_CONCURRENT);
        dispatch_async(queue, ^{
            NSLog(@"1 --- %@", [NSThread currentThread]);
            dispatch_sync(queue, ^{
                NSLog(@"2 --- %@", [NSThread currentThread]);
            });
        });
    }
    
    实现:

    根据GCD执行方式,可将其分为几种类型
    根据线程执行方式分为同步:同一个线程顺序执行 异步:不在一个线程执行
    根据任务执行方式串行:串在一起执行 并行:一起执行
    主队列不会开辟新的线程,所以使用主线程执行任务只有同步串行一种方式

    // 此处只实现异步并发方式
    // 异步 + 并发队列 具备开启子线程的能力,并且并发执行任务
    - (void)createAsyncConcurrent
    {
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_async(queue, ^{
            NSLog(@"1 --- %@", [NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            NSLog(@"2 -- %@", [NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            NSLog(@"3 --- %@", [NSThread currentThread]);
        });
    }
    
    

    相关文章

      网友评论

          本文标题:iOS开发随性总结之多线程

          本文链接:https://www.haomeiwen.com/subject/wegbjttx.html