多线程基础知识了解一下

(一) 前言

作为一名优秀的攻城师,了解多线程的知识非常有必要,尤其在人工智能和机器学习的热潮下,如何提高程序或者算法的运行效率是非常有价值的一件事情。

在当代大多数的操作系统,都有能力同时的运行多个程序或者app,比如在windows上你可以同时打开多个QQ,多个不同的浏览器,多个不同的视频播放器。或者在你的苹果或者安卓手机上边听歌边使用地图功能,这背后其实用的就是用的是多线程的技术。

(二)多任务处理

在同一时刻运行多个程序也叫做多任务处理,每个程序会由一个单独的task来执行,每个task运行在一个单独的处理器中(可以理解为是一个进程或者一个CPU)。在早期的计算机操作系统中,往往都是单处理器的,这时候你也能同时运行多个程序,这种情况我们称为并发而不是并行,因为这个时候多个程序其实是共用的一个CPU时钟,由于计算机的时间片切换非常快,所以大多数时候你是感觉不到这种差异的,但其实是一种假象。随着社会的进步,现在的电脑基本上都是多个CPU的,所以在多个CPU的情况下,程序才能够真正的并行起来。

(三)线程与多线程

每个处理器可以创建多个子任务,这里的每一个子任务都是一个线程。一个线程执行的其实就是一段代码指令序列。在一个处理器内的多个线程是可以通过处理器的共享内存进行交互的,关键词并发(concurrency)指的就是在一个处理器内同时执行多个线程。

多线程通常是通过把大的任务切分成多个子任务运行,以此来提高程序运行效率的。比较典型的例子就是现实中修一段高速公路时,最快的方法就是,把这条公路切分成多段,然后每个段由一个工程队负责,这样同时工作就能大大提高效率。

(四)并发与线程上下文切换

上面说过,单个处理器内的多线程任务其实是一种假象,其实是通过切换CPU时钟实现的,这个时候,在切到另一个线程之前,CPU必须保存当前线程的状态,这被称为上下文切换,这也是单核处理器能同时执行多个任务的秘密。

线程切换是一个比较昂贵的操作,调度器需要花费额外的CPU时间来临时暂停当前活跃的线程为了让另外一个线程运行,然后保存当前线程状态,在需要的时候,还得恢复当前挂起的线程状态。

(五)线程调度

线程调度主要负责线程的上下文切换,它决定了接下来要选择哪个挂起的线程执行。线程调度是操作系统的一部分。

(六)互斥

互斥的目的是保证在两个线程之间不能同时执行同一个代码片段。通俗点来说就是我们在大街上看到的红绿灯,任何时候只能有一种颜色的灯在亮。 互斥的资源通常是需要被共享的,比如卫生间的马桶,任何时候只能有一个人用,如果同时有多个人用那么就会出现问题,这也叫竞争,反映到程序中,可能是一种数据解构,一个外部设备如打印机,或者一个网络连接。

竞争通常会带来问题,所以在程序中通常使用锁机制(lock)来达到互斥的目的,互斥也可以称为线程同步(synchronization)

同步带来的缺点是,在一个线程没有释放锁之前,另外一个线程需要一直等待。它强制调度是串行操作的,即使这里有多个空闲的CPU资源,所以在日常开发中要合理使用。

(七)并发与并行

并行:

并行指的是多线程运行在不同的CPU或者处理器上,从而避免了在同一个CPU或者处理器中的上下文切换的操作。当然这里是多个线程之间不需要通信或者有共享资源需要访问。这种情况就可以独立的执行和计算。当然前提是硬件有多个CPU或者处理器。

并发:

并发指的是多个线程有通信或者需要访问共享的数据,这个时候需要考虑加锁,否则有可能安全问题。通常情况下并发是指运行在同一个CPU或者core内,但这并不是十分准确,多个线程也可以运行在多个CPU内但是他们有合理的同步策略。

(八)多处理器 vs 多core vs 超线程

多处理器是指在单台电脑上有多个CPU单元,每一个处理器可以有多个core,每个core可以运行一个任务,多线程程序每个线程都可以并行的运行在一个core中。

注意单个core也有可能运行两个并行的线程,这种能力被称为超线程。

超线程(HT, Hyper-Threading)[1]是英特尔研发的一种技术,于2002年发布。超线程技术原先只应用于Xeon 处理器中,当时称为“Super-Threading”。之后陆续应用在Pentium 4 HT中。早期代号为Jackson。 通过此技术,英特尔实现在一个实体CPU中,提供两个逻辑线程。之后的Pentium D纵使不支持超线程技术,但就集成了两个实体核心,所以仍会见到两个线程。超线程的未来发展,是提升处理器的逻辑线程。英特尔于2016年发布的Core i7-6950X便是将10核心的处理器,加上超线程技术,使之成为20个逻辑线程的产品。

超线程其实是一个CPU单元内,提供了两个逻辑线程,依赖于底层操作系统,如果操作系统不支持,也可以禁用掉。因此在一个4 core 处理器系统中可能有8个逻辑处理器。

(九)线程 与 CPU缓存

依赖于CPU的类型,当前的操作系统基本都支持三级缓存,CPU缓存的目的是为了CPU访问CPU缓存数据更快,这种快是相对于CPU读取内存数据而言(RAM),通常情况下一般高出几个数量级。

L1 级别缓存 在cpu的芯片中,体积一般是8-64kb

L2 级别缓存 通常位于CPU和RAM之间,体积一般是2-4MB

L3 级别缓存 如果存在一般都位于主板上,体积一般是8-16MB (注:跟CPU类型有关,一些CPU类型可能直接用L2替代L3了)

下面通过表格看下不同的介质,访问的耗时情况,其中L1缓存属于core级别的,所以每个运行在core里面的线程都可以拥有自己的local cache。

从CPU到

大约需要的CPU周期

大约需要的时间(单位ns)

寄存器

1 cycle

可以忽略

L1 Cache

~3-4 cycles

~0.5-1 ns

L2 Cache

~3-4 cycles

~0.5-1 ns

L3 Cache

~3-4 cycles

~0.5-1 ns

跨槽

~30-40 cycles

~20 ns

内存

~120-240 cycles

~60-120ns

(十) 总结

本篇主要介绍了多线程有关的一些基础概念以及CPU的cache模型,在一个多线程的程序中,为了提高处理性能,每个线程都有自己的CPU缓存,而同时如果多个线程想要访问一块共享的区域(位于主内存中),需要考虑同步和可见性的问题,,所以一些编程语言如C,C++,C#和Java都会有确保变量在修改之后对其他线程可见的语义,如Java里面的volatile关键词会强制flush线程的local cache的数据到主存中,除此之外一些锁机制也会触发,如lock和unlock指令,这些知识点会在后面的文章中介绍。

原文发布于微信公众号 - 我是攻城师(woshigcs)

原文发表时间:2018-06-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏代码GG之家

只需一个命令,快速定位android的启动耗时

有兴趣合作,帮忙制作公众号的一些宣传图册的伙伴,可以加我微信,商谈具体事宜。 回顾: Android 启动过程框架 这节我们讲一个命令,用来定位android...

2036
来自专栏大数据智能实战

protobuf 转换python代码时发生 Expected "required", "optional", or "repeated".错误解决方法

        Google Protocol Buffers 简称 Protobuf,它提供了一种灵活、高效、自动序列化结构数据的机制,可以联想 XML,但是...

2468
来自专栏云之翼

在虚拟机上容器环境性能--动态测试问题分析总结(二)

在上一篇中,介绍了静态测试场景,本文介绍动态性能测试的差异分析,希望大家可以借鉴。

1370
来自专栏MongoDB中文社区

完美数据迁移-MongoDB Stream的应用

尽管如此,目前还是有许多企业踏上了服务化改造的道路,这其中则免不了”旧改”的各种繁杂事。

1162
来自专栏编程

教你从零开始搭建一款前端脚手架工具

本文系原创,转载请注明:作者:Jrain Lau(https://segmentfault.com/u/jrainlau)项目地址:https://github...

4637
来自专栏Java职业技术分享

并发模型比较

Golang 的特色之一就是 goroutine ,使得程序员进行并发编程更加方便,适合用来进行服务器编程。作为后端开发工程师,有必要了解并发编程面临的场景和常...

3690
来自专栏我是攻城师

多线程基础知识了解一下

作为一名优秀的攻城师,了解多线程的知识非常有必要,尤其在人工智能和机器学习的热潮下,如何提高程序或者算法的运行效率是非常有价值的一件事情。

2633
来自专栏Ceph对象存储方案

RGW Bucket Shard设计与优化-上

1 bucket index背景简介 bucket index是整个RGW里面一个非常关键的数据结构,用于存储bucket的索引数据,默认情况下单个bucke...

1.2K5
来自专栏Java后端技术栈

为什么说Redis是单线程的?

近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是“二八定律”、什么是“热数据和冷数据” ,复杂一点的会问到缓存雪崩、缓存穿透、缓存预热、缓...

1472
来自专栏技术小黑屋

快速提高Android开发效率的Web工具

在Google的广大支持下,便捷开发Android程序的Native工具层出不穷。其实Android开发涉及到的范围也不小,一些Web工具有时候也会带来事半功倍...

1552

扫码关注云+社区

领取腾讯云代金券