美文网首页
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