进程、线程,cpu核数的关系

title

文章背景

最近写了一个关于多线程的脚步,才发现自己把好多计算机操作系统的知识都忘记了,所以稍微恶补了一下相关知识,以下是自己的理解,如有错误,欢迎大家指正。

cpu架构

计算机有5大基本组成部分,运算器,控制器,存储器,输入和输出。运算器和控制器封装到一起,加上寄存器组和cpu内部总线构成中央处理器(CPU)。

cpu又分为单核cpu和多核cpu,不同的机器的cpu个数也不同。

多核cpu的架构如下:

multi-core

多核CPU,不同的核通过L2 cache进行通信,存储和外设通过总线与CPU通信。

多cpu的架构如下:

multi-cpu

多个物理CPU,CPU通过总线进行通信,效率比较低。

cpu的知识还有很多,譬如寄存器和三级缓存等等,下来继续研究

cpu个数、核心数、多线程、多进程的关系

进程

进程是资源分配的最小单位,一个程序有至少一个进程。

进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。

进程之间的通信需要以通信的方式(IPC)进行。

线程

线程是程序执行的最小单位。一个进程有至少一个线程。

线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。

线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据。

进程与线程的关系

一个进程有至少一个线程。一个线程只能在一个进程中。

多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。

多进程

同一个时间里,同一个计算机系统中允许两个或两个以上的进程处于并行状态,这是多进程。多进程带来的好处是你可以边听mp3边上网,与此同时甚至可以将下载的文档打印出来,而这些任务之间丝毫不会相互干扰。但并行需要解决的问题是通常并行的进程比CPU数量多得多,而原则上一个CPU只能分配给一个进程(引入线程后,CPU调度的基本单位是线程,进程是资源分配的最小单位),以便运行这个进程。而要让CPU同时运行多个进程,就必须使用并发技术,实现并发技术最常见的就是时间片轮转调度算法,即在操作系统的管理下,所有正在运行的进程轮流使用CPU,每个进程允许占用CPU的时间非常短(比如1毫秒),这样用户根本感觉不出来 CPU是在轮流为多个进程服务,就好象所有的进程都在不间断地运行一样,给用户的感觉就是并行。但实际上在任何一个时间内有且仅有一个进程占有CPU。

所以对于多cpu,多个进程可以并行在多个cpu中计算,当然也会存在进程切换;

对于单cpu,多个进程在这个单cpu中是并发运行,根据时间片读取上下文+执行程序+保存上下文。

同一个进程同一时间段只能在一个cpu中运行,如果进程数小于cpu数,那么未使用的cpu将会空闲。

父进程和子进程

为啥引入子进程:
为什么引入进程,因为并发,那么为啥引入子进程呢,这个答案也是因为进一步的并发,比如我想算一下a * 100,我还想算b * 100,我可以顺序算,也可一创建两个子进程一个算前者,一个算后者,父进程等待算好了,拿过来用,这是进一步的并发。

关于资源:子进程得到的是除了代码段是与父进程共享的以外,其他所有的都是得到父进程的一个副本,子进程的所有资源都继承父进程,得到父进程资源的副本,既然为副本,也就是说,二者并不共享地址空间。两个是单独的进程,继承了以后二者就没有什么关联了,子进程单独运行。(采用写时复制技术)

关于文件描述符:继承父进程的文件描述符时,相当于调用了dup函数,父子进程共享文件表项,即共同操作同一个文件,一个进程修改了文件,另一个进程也知道此文件被修改了。

父进程创建两个子进程,子进程是对父进程的克隆,两个子进程是完全独立的,不能互相访问。

从上面可以看出:子进程与单独起一个进程的差别不是太大,但仍然有自己的适用范围,比如主程序可以调用别人的程序,或者是一些权限的问题,在权限敏感的程序里,子进程会继承部分权限。

子进程和线程区别

举例而言,进程和线程的区别在于粒度不同, 进程之间的变量(或者说是内存)是不能直接互相访问的, 而线程可以, 线程一定会依附在某一个进程上执行.我举个例子, 你在Windows下开一个IE浏览器, 这个IE浏览器是一个进程. 你用浏览器去打开一个pdf, IE就去调用Acrobat去打开, 这时Acrobat是一个独立的进程, 就是IE的子进程.而IE自己本身同时用同一个进程开了2个网页, 并且同时在跑两个网页上的脚本, 这两个网页的执行就是IE自己通过两个线程实现的.值得注意的是, 线程仍然是IE的内容, 而子进程Acrobat严格来说就不属于IE了, 是另外一个程序.之所以是IE的子进程, 只是受IE调用而启动的而已.

多线程

线程是进程中的单位,是占用CPU的单位,例如4内核CPU,如果有4个线程,这个4个线程是并行(不是并发)。

超线程(Intel技术)

在这里插入图片描述

这就是我们购买电脑时,所看到的CPU参数:该电脑拥有1个CPU,它有4个内核(表示有4个相对独立的CPU核心单元组,这是物理概念),每个内核有个4线程(这是逻辑概念。即 超线程技术,它可以实现单个物理核实现线程级别的并行计算。也就是说:OS会认为一个线程也是一个内核,当然这是OS的“错觉”)。

上述这个CPU可描述为:单CPU 4核心 4线程

4核 指的是物理核心(物理概念)。4线程(线程数是一个逻辑概念) 是通过超线程技术,用一个物理核模拟两个虚拟核(逻辑处理器),所以每个物理核2个线程,总数为8线程,在操作系统看来是8核,实则是4个物理核。

尽管现在有4个物理核,4个逻辑核,但是实际性能还是不如真正的8核处理器好。因为超线程技术本身是复用相同的物理核心,当前场景每个线程执行的功能类似,因此使用超线程时,两个线程使用同一个物理核心上的同一个执行部件,同时内存压力加倍,造成线程等待。(而且这个还是根据实际的业务代码决定,有的代码跑起来,物理4线程比超线程的8线程性能还好。)

我们都知道,一个核心同时只能运行一个线程。那么在超线程技术中的线程是否是真正的并行呢?

根据我自己了解到的:Intel的超线程技术,目的是为了更充分地利用一个单核CPU的资源。CPU在执行一条机器指令时,并不会完全地利用所有的CPU资源,而且实际上,是有大量资源被闲置着的。超线程技术允许两个线程同时不冲突地使用CPU中的资源。比如一条整数运算指令只会用到整数运算单元,此时浮点运算单元就空闲了,若使用了超线程技术,且另一个线程刚好此时要执行一个浮点运算指令,CPU就允许属于两个不同线程的整数运算指令和浮点运算指令同时执行,这是真的并行。

但是也不是所有的线程都是并行的,只能说恰好碰到两个线程当前要执行的指令不使用相同的CPU资源时才可以真正地并行执行。

总结

单CPU中进程只能是并发,多CPU计算机中进程可以并行。

单CPU单核中线程只能并发,单CPU多核中线程可以并行。cpu核心数越高,多线程并行数越高。

对普通用户来说,进程和线程宏观上都是并行的。

超线程技术可以提高cpu核心的利用率(只针对多线程),提高的性能也不是直接翻倍 。 一般也就提高百分之10-30吧,有的时候甚至还有性能衰减o(╥﹏╥)o哈哈

相关链接:

https://www.cnblogs.com/move-on-change/p/9534045.html

https://medium.com/mineiros/how-to-use-multithreading-and-multiprocessing-a-beginners-guide-to-parallel-and-concurrent-a69b9dd21e9d