你的位置:首页 > 操作系统

[操作系统]浅谈多线程


写这篇博客的目的是为了跟大家分享本人对多线程的一些浅显的理解,顺道梳理一遍自己掌握的知识,如有不妥之处,欢迎各位大牛指正.

 

首先要理解两个概念:

进程(Process):程序的一次运行,拥有独立的内存地址空间(一个iOS应用只有一个进程).

线程(Thread):

1.线程是进程的基本执行单元,是操作系统可以调度的最小单元,一个进程中可以有多个线程,也至少有一个线程.

2.多个线程共用进程的地址空间,每个线程都有自己的栈空间,共用堆空间.

3.多个线程可以同步执行,目的在于提高CPU资源利用率.

 

多线程优缺点:

优点:可以提高CPU利用率,防止阻塞主线程,避免使UI出现假死(卡顿)现象,这里提醒大家,程序展现给用户看的,有关UI界面的更新尽可能的在主线程中处理,主线程也尽可能的只处理UI的更新和展示,其他的比如数据的处理之类的操作都放到子线程中,这样就避免了用户与应用界面的交互出现卡顿延迟现象.

缺点:每个线程都有自己的线程栈,需要占据一定的空间;线程调度需要消耗CPU时间;程序设计更加复杂,需要考虑线程间通信、数据共享和数据安全等问题。

 

iOS多线程的方法:

1.C语言接口:pthread.

2.NSThread

3.NSOperation

4.GCD

这里暂时只介绍GCD.

GCD(Grand Central Dispatch)是一种异步执行任务的技术。封装了多线程开发中的难点“线程管理”,开发者只需要定义任务,并提交到分发队列(Dispatch Queue),由GCD自动管理和调度。

GCD使用block定义任务,可以同步或者异步提交任务。

//同步提交任务

dispatch_sync(queue,^{

/*任务*/

};

//异步提交任务

dispatch_async(queue,^{

/*任务*/

};

queue为任务队列

dispath_sync方法会等待任务执行完成才返回,等待意味着执行dispatch_sync的线程“暂停”,且不能提交任务到当前线程(提交任务的线程,易死锁)。

dispath_async方法不会等待任务执行完成就会返回。

 

队列的类型:

GCD有两种队列类型:

串行队列:等待前一个任务执行完成。串行队列中的任务按先进先出(FIFO)的规则执行,并且前一个任务执行完,才能处理后一个任务,且只使用一个线程处理队列。

并行队列:不等待前面的任务执行完成。并行队列使用多个线程同时处理队列,同时执行的任务数与线程的数目有关,线程的数目与CPU核心数目、CPU负载等相关,打个比方,并行队列下有一个任务:从1数到100

    for (int i = 0; i < 100; i++) {

  //此方法是获取系统全局队列,全局队列是一个并行队列。
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
          
            NSLog(@"i = %d",i);
        });
    } 

能发现进程ID始终是58251,而线程ID却有多个,打印的数字也不是按照规范的顺序,这是因为线程异步处理的原因,每个线程都在“争抢”执行任务,而CPU会根据目前的状态安排一定数目的线程执行任务,每一个线程执行完任务后继续执行下一个任务。

--------睡觉分割线,有空再接着写-------