iOS多线程浅汇-原理篇

一、前言

多线程这个词对于大家来说并不陌生,但是真正能够熟知多线程的坑点只在少数,iOS中并行也一直被认为是恶魔,有时候会出现很多莫名其妙的bug。

大家都知道:

新开一条线程,提高程序运行效率,避免阻塞主线程

但是有时候,多开一条线程只意味着多一条线程的性能损耗。

除此之外熟练掌握原理,特别是对于几个常见的概念(同步,异步,串行,并行)理解得十分透彻的确实不多,可能有许多人和我一样处于似懂非懂的状态。带着这个困惑,翻看了许多博文还有apple的官方文档,整理了下有关多线程编程的原理部分内容,多线程实践篇请移步iOS多线程浅汇-实战篇

二、基本概念

  • 进程:

一个具有一定独立功能的程序关于某个数据集合的一次运行活动

文档中关于进程的描述:

The term process is used to refer to a running executable, which can encompass multiple threads.

系统中正在运行的一个应用程序就是一个进程,每个进程都运行在自己独有的受保护的内存中。在iPhone中,每一个APP都是一个进程。

  • 线程:

    The term thread is used to refer to a separate path of execution for code.

    线程是指可独立执行的代码路径,它程序执行流的最小单元,是进程中的一个实体,是执行程序最基本的单元,有自己栈和寄存器。

    一个进程的所有任务都在线程中进行,因此每个进程都至少有一个线程,这个线程被称为主线程

  • 多线程:
    一个进程可以开启多条线程,让所有任务异步执行。

  • 同步:
    只能在当前线程下按按照FIFO(先进先出)的规则顺序执行,当前任务会阻塞下一个任务。如果在同步线程下开了更多的线程,只会造成资源的浪费。比如开了三条线程,每个任务都需要等待上一个任务结束才能被处理,这种情况下系统就必须在三个线程之间来回切换。线程有自己的栈和寄存器,三个线程就有三组栈和寄存器中的值需要不断地被备份、替换。这相对于只有一组栈和寄存器(只有一条线程)来说,效率肯定大大降低了。当开发者使用GCD和NSOperation的时候,系统会默认只在一条线程,避免造成资源浪费。

  • 异步:

an asynchronous function does some work behind the scenes to start a task running but returns before that task might actually be complete. Typically, this work involves acquiring a background thread, starting the desired task on that thread, and then sending a notification to the caller (usually through a callback function) when the task is done.

异步方法在执行的时候,不会等到其内部代码全部执行完毕才返回,而是立即返回往下执行,在另一条线程中执行内部代码。

异步与同步的区别在于当前任务不会阻塞下一个任务的进行,当一条线程中的当前任务还未执行完毕,而另一条线程没有任务正在执行时,CUP就会将下一个任务分配给空闲的线程,由于CUP的速度够快,所以看起来每个任务都是同时进行的。

  • 并发(concurrency):

Concurrency is the notion of multiple things happening at the same time

并发形容的是许多任务在同一时间需要处理,侧重在于“发生”。

  • 并行(parallel)
    指的是有许多任务同时在运行,侧重在“运行”。
  • 队列:
    装载线程任务的队形结构

  • 调度队列(dispatch queue)&操作队列(operation queue)

A dispatch queue executes tasks either serially or concurrently but always in a first-in, first-out order

iOS中的队列(准确的说应该是GCD和NSOperation才引入的概念)是用于管理任务的执行方式,dispatch queue是GCD下的方式,它是C底层机制的;operation queue是NSOperation的方式,但是和dispatch queue的用法和管理任务的机制几乎是一样的,NSOperation是在OC层面上对GCD的封装。
唯一的区别在于:

Whereas dispatch queues always execute tasks in first-in, first-out order, operation queues take other factors into account when determining the execution order of tasks

operation queue在决定任务的执行顺序的时候会考虑其他因素,比如是否添加了依赖等

队列又分为串行队列和并行队列:

  • 串行队列:

Serial queues (also known as private dispatch queues) execute one task at a time in the order in which they are added to the queue. The currently executing task runs on a distinct thread (which can vary from task to task) that is managed by the dispatch queue

串行队列(也称私人队列)在一个时间内只会执行一个任务。线程里的任务按照顺序执行,同步执行:只有一个线程,且每个任务按照顺序依次执行;异步执行:有多个线程,每个线程中的任务按照顺序执行。

串行队列的每个队列中一次只能执行一个任务,但是系统并没有限制开发者只能有一个队列,开发者同样可以通过串行队列实现并发任务的处理。

if you create four serial queues, each queue executes only one task at a time but up to four tasks could still execute concurrently, one from each queue.

如果创建了四个串行队列,每个队列中的一次只执行一个任务,这样就能做到在同一时间执行四个任务。

  • 并行队列:

Concurrent queues (also known as a type of global dispatch queue) execute one or more tasks concurrently, but tasks are still started in the order in which they were added to the queue. The currently executing tasks run on distinct threads that are managed by the dispatch queue. The exact number of tasks executing at any given point is variable and depends on system conditions.

并行队列(全局队列)可以同时执行多个任务,任务也是按照添加到队列的顺序执行的,当期运行的任务在后台线程执行,由dispatch queue负责调度,系统会根据系统状况决定一次能执行的最多任务数。

In iOS 5 and later, you can create concurrent dispatch queues yourself by specifying DISPATCH_QUEUE_CONCURRENT as the queue type.In addition, there are four predefined global concurrent queues for your application to use

iOS5以后,apple允许开发者自己创建并行队列,同时,apple还提供了四个已经创建好的全局队列供开发者使用,只需要获取就行。

note:同步执行:只有一个线程,所以没办法多个任务同时执行;异步执行:有多个线程,多个线程中的多个任务可以同时进行。

三、举个栗子

用一个例子说明同步异步,串行并行之间的主要功能。

现在你有三个耗时任务task1,task2,task3,分别用时为2s,1s,1s。

这里需要清楚一个概念:**线程是“一个CPU执行的一条无分叉的命令列”,单核CPU上,同一时刻只能有一条线程运行 **。
对于串行并行来说,是执行速度上的概念,如果有三个CUP同时执行,三个任务的执行时间为2s,因为三个任务可以同时执行,

对于同步异步来说,是执行顺序上的概念,如果加入task1为下载图片的任务,而task2和task3是UI相关的任务,使用异步执行task1,减少了2s的卡顿时间,在这个期间用户仍然可以触摸滚动。

如果使用GCD和NSOperation,由于系统会帮开发者管理线程的生命周期.

四、图解多线程

这张图对于iOS中的常用的多线程知识整理挺全面,看完对这部分知识会用一个更全局的了解:

图解多线程

阅读原文

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,069评论 4 358
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,212评论 1 287
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 105,912评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,424评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,741评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,194评论 1 206
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,553评论 2 307
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,289评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,923评论 1 237
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,251评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,775评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,144评论 2 249
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,698评论 3 228
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,936评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,658评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,214评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,159评论 2 258

推荐阅读更多精彩内容