多线程-概述及底层实现机制浅析

Paste_Image.png

前言

在打算写这篇多线层底层实现机制的时候,突然发现自己对于计算机竟然懂得这么表面,对于CPU的工作原理都不完全清楚,于是又转头查看了一些CPU相关的资料。也不敢钻的太深,怕自己迷路...,其中如有错误,望知道的朋友在下面留言评论,我会及时更新的。


关于CPU

CPU(中央处理器)顾名思义是电脑中处理器的总部(电脑里几个重要的硬件都自带的有自己的处理器,比如,GPU是显卡自己的处理器等),负责整个电脑的运行调度。它是指挥者,所以最底层的一些工作并不是由CPU来完成的。CPU以及高的速度再运转,它的运行是由一串串数字脉冲信号通过硅晶版上的晶体管实现的,那一波波的数字脉冲信号震荡的速度,就是CPU那传说中的主频

CPU的主频与CPU实际的运算能力并没有直接关系。如今的CPU工艺先进,运算流水线短,其主频的高低在一定意义上又可以体现CPU性能的高低。CPU的主频不代表CPU的速度,但提高主频对于提高CPU运算速度却是至关重要的。

关于CPU使用率,其实就是你运行的程序占用的CPU资源,表示你的机器在某个时间点的运行程序的情况。使用率越高,说明你的机器在这个时间上运行了很多程序,反之较少。使用率的高低与你的CPU强弱有直接关系。现代分时多任务操作系统对 CPU 都是分时间片使用的:比如A进程占用10ms,然后B进程占用30ms,然后空闲60ms,再又是A进程占10ms,B进程占30ms,空闲60ms;如果在一段时间内都是如此,那么这段时间内的占用率为40%。CPU对线程的响应并不是连续的,通常会在一段时间后自动中断线程。未响应的线程增加,就会不断加大CPU的占用。

操作系统的设计,可以归结为三点:

  • (1)以多进程形式,允许多个任务同时运行;
  • (2)以多线程形式,允许单个任务分成不同的部分运行;
  • (3)提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。
CPU型号 CPU内核信息
I3 双核四线程
I5 双核四线程
I5 四核四线程
I7 四核八线程
I7 六核十二线程

关于CPU的详细介绍可以看这里

关于多核、多处理器、多线程

了解了CPU的工作机制,我们再来分析一下CPU的多核、多处理器,与多线程。也许有人会问:“了解这些有什么卵用”,其实在我看来,详细了解这些硬件对于我们理解多线程技术的必要性和开展多线程编程都是很必要的,可以提供宏观的理论依据。

多核

CPU的性能主要靠提高核心工作频率来提高,由于物理限制,不能把CPU的核心频率无限提高,所以发展出来双核心或多核心的CPU。相当于在一枚处理器上集成多个完整的计算引擎(内核),他们共享缓存,内存,寄存器等。

,是物理的,几核就是真的有几个物理核心。线程就是英特尔的超线程技术。是在一个实体处理器中,提供两个逻辑线程。线程是虚拟的,不是真实存在的。但性能上,会模拟真实的核。也就是说,双核4线程,看起来很像4核,但比真实的4核4线程慢,却比双核双线程快。

手机多核其实应该叫多CPU,将多个CPU芯片封装起来处理不同的事情,你甚至可以戏称为“胶水核心”,也就是被强行粘在一起的意思。在待机或者空闲的时候,八核的手机也只能用到一到两个核心。

而电脑则不同,PC的多核处理器是指在一个处理器上集成了多个运算核心,通过相互配合、相互协作可以处理同一件事情,是多个并行的个体封装在了一起。用一句话概括,就是并行处理,双核就是单车道变多车道
我们都知道智能手机都是有CPU的,iPhone6使用的A8处理器是一款双核处理器。

多处理器(多CPU)

多处理器系统是指包含两台或多台功能相近的处理器(多CPU),处理器之间彼此可以交换数据,所有处理器共享内存,I/O设备,控制器,及外部设备,整个硬件系统由统一的操作系统控制,在处理器和程序之间实现作业、任务、程序、数组极其元素各级的全面并行。目前主流的服务器架构,超级计算机等等,都是多CPU多核架构。

多线程

多线程是为了使得多个线程并行的工作以完成多项任务,以提高系统的效率。线程是在同一时间需要完成多项任务的时候被实现
的。

多线程实现的相关讨论

下面进入到正餐了,在讨论多线程之前,我们需要先认识一下,进程、线程,以及相关值得注意的问题。

什么是线程、进程

来来来,先读一个有趣的故事《进程与线程的一个简单解释》,浅显易懂,生动形象地解释了多项成相关的很多典型问题。通过上文我们大致可以宏观了解这些问题了。

进程: 进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。进程是计算机中已运行程序的实体。其本身并不是几部运行单位,是线程的容器。
线程: 线程是操作系统能够进行运算调度的最小单位。线程是一组指令的集合它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。线程是独立调度和分派的基本单位。同一进程中的多条线程将共享该进程中的全部系统资源,但是自有调用堆栈和寄存器环境。

线程、进程的不同

主线程在程序中的地位和其他线程不同,它是其他线程最终的父线程,且所有界面的显示操作即AppKit或 UIKit的操作必须在主线程进行。

进程和线程都是操作系统的概念。进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成。

线程和进程十分相似,不同的只是线程比进程小。首先,线程采用了多个线程可共享资源的设计思想;例如,它们的操作大部分都是在同一地址空间进行的。其次,从一个线程切换到另一线程所花费的代价比进程低。再次,进程本身的信息在内存中占用的空间比线程大,因此线程更能允分地利用内存。

线程是进程的一部分
CPU调度的是线程
系统为进程分配资源,不对线程分配资源

进程和线程的关系:

一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。 资源分配给进程,同一进程的所有线程共享该进程的所有资源。 处理机分给线程,即真正在处理机上运行的是线程。 线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

为什么要实现多线程

多线程技术的出现,主要是因为多任务的需要,比如我想同时写文章和听歌,如果我们的CPU一直被写文章的任务占着,等写文章的任务结束后,再播放歌曲,很显然达不到需要的“同时”做两件事的效果。

多线程的出现也是多核CPU、多处理器计算机普及的需要,这样可以提高CPU的利用率,增加并发性,提高程序的执行效率,更快的处理完任务。

在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较游泳了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。

多线程为何能实现

单就一个CPU而言两个线程可以解决线程阻塞造成的不流畅问题,其本身运行效率并没有提高,多CPU的并行运算才真正解决了运行效率问题,这也正是并发和并行的区别。当然,不管是多核还是单核开发人员不用过多的担心,因为任务具体分配给几个CPU运算是由系统调度的,开发人员不用过多关心系统有几个CPU。开发人员需要关心的是线程之间的依赖关系,因为有些操作必须在某个操作完成完才能执行,如果不能保证这个顺序势必会造成程序问题。
每个线程被分配一个时间段,称作它的时间片,即该进程允许运行的时间,使各个程序从表面上看是同时进行的。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。而不会造成CPU资源浪费。在宏观上:我们可以同时打开多个应用程序,每个程序并行不悖,同时运行。但在微观上:由于只有一个CPU,一次只能处理程序要求的一部分,如何处理公平,一种方法就是引入时间片,每个程序轮流执行。调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。

每个进程都有私有的虚拟地址空间,进程的所有线程共享同一地址空间。每个线程被CPU分配一个时间片,一旦被激活,它正常运行直到时间片耗尽并被挂起,此时,操作系统选择另一个线程进行运行。通过时间片轮转,又出于各个时间片很小(20毫秒级),看起来就像多个线程同时在工作。实际上,只有在多处理器系统上才是真正的在可得到的处理器上同时运行多个线程。

从一个进程切换到另一个进程是需要一定时间的--保存和装入寄存器值及内存映像,更新各种表格和队列等。假如进程切换(process switch) - 有时称为上下文切换(context switch),需要5毫秒,再假设时间片设为20毫秒,则在做完20毫秒有用的工作之后,CPU将花费5毫秒来进行进程切换。CPU时间的20%被浪费在了管理开销上。

时间片设得太短会导致过多的进程切换,降低了CPU效率;而设得太长又可能引起对短的交互请求的响应变差。将时间片设为100毫秒通常是一个比较合理的折衷。

线程越多越好吗

线程多了可以提高程序并行执行的速度,但是并不是越多越好。
其一,每个线程都要占用内存,多线程就意味着更多的内存资源被占用,开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能。
其二,从微观上讲,一个cpu不是同时执行两个线程的,他是轮流执行的,所以线程太多,cpu必须不断的在各个线程间快回更换执行,线程间的切换无意间消耗了许多时间,所以cpu有效利用率反而是下降的

开发中实现多线程的方案

Mach是第一个以多线程方式处理任务的系统,因此多线程的底层实现机制是基于Mach的线程。
然后开发中很少用Mach级的线程,因为Mach级的线程没有提供多线程的基本特征,线程之间是独立的

多线程的方案有以下几种

  • C语言的POSIX接口方案

    Pthreads定义了一套C语言的类型、函数与常量,它以pthread.h头文件和一个线程库实现。线程库实行了POSIX线程标准通常称为Pthreads。POSIX线程具有很好的可移植性,使用pthreads编写的代码可运行于Solaris、FreeBSD、Linux 等平台,Windows平台亦有pthreads-win32可供使用。而且你需要手动处理线程的各个状态的转换即管理生命周期,比如,这段代码虽然创建了一个线程,还需要销毁这个线程。感兴趣的朋友,或者说想要自己实现一套多线程方案,从底层开始定制,那么可以去搜一下相关资料研究一下。

  • OC的NSThread方案。是对POSIX thread的封装
  • C语言的GCD接口方案(性能最好,代码更精简)。
  • OC的NSOperation和NSOperationQueue(基于GCD)方案。

小结

本文洋洋洒洒写了好多看似跟多线程无关的东西,其实我认为这些对之后多线程的学习是有帮助的,如果你认真对了本文,相信你会对多线程有更深的理解,作为多线程系列的开胃菜,本文到此就结束了,后续会陆续发布多线程相关的文章,如有不对之处,还望观看的朋友,在下面的评论区指出,thanks.

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

推荐阅读更多精彩内容