进程和线程的区别
1. 从 计算机操作系统的角度理解进程和线程
进程的概念:正在运行的一个程序或者任务就叫进程。比如一个正在运行的xx.exe就是一个进程。
【负责执行任务的是CPU】
线程的概念:线程是CPU上的最小执行单位。即进程中的一个执行任务,负责当前进程中程序的执行。
程序执行的过程其实是执行具体的线程,那么处理机处理的也是程序相应的线程,所以处理机调度的基本单位是线程。
举例子说明:
做个简单的比喻:进程=火车,线程=车厢
线程在进程下行进(单纯的车厢无法运行)
一个进程可以包含多个线程(一辆火车可以有多个车厢)
不同进程间数据很难共享(一辆火车上的乘客很难换到另外一辆火车,比如站点换乘)
同一进程下不同线程间数据很易共享(A车厢换到B车厢很容易)
进程要比线程消耗更多的计算机资源(采用多列火车相比多个车厢更耗资源)
进程间不会相互影响,一个线程挂掉将导致整个进程挂掉(一列火车不会影响到另外一列火车,但是如果一列火车上中间的一节车厢着火了,将影响到所有车厢)
进程可以拓展到多机,进程最多适合多核(不同火车可以开在多个轨道上,同一火车的车厢不能在行进的不同的轨道上)
进程使用的内存地址可以上锁,即一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。(比如火车上的洗手间)-"互斥锁"
进程使用的内存地址可以限定使用量(比如火车上的餐厅,最多只允许多少人进入,如果满了需要在门口等,等有人出来了才能进去)-“信号量
进程和线程的区别:
- 根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位
计算机在执行程序时,会为程序创建相应的进程,进行资源分配时,是以进程为单位进行相应的分配,每个进程都有相应的线程,在执行程序时,实际上是执行相应的一系列线程。
image.png2.地址空间: 进程有自己独立的地址空间,每启动一个进程,系统都会为其分配地址空间,线程没有独立的地址空间,同一进程的线程共享本进程的地址空间。
3.资源拥有: 进程之间的地址空间和资源是相互独立的,同一进程内的线程共享本进程的地址空间和资源。
image.png
4.资源开销:创建进程的开销要远大于创建线程的开销。(因为:创建进程涉及到申请空间,而且在该空间内至少创建一个线程,而创建线程不需要申请空间,共享进程空间,所以开销小。)-----》总结:程序之间的切换会有较大的开销, 线程之间的切换开销小。
5.包含关系:一个进程内可以包括多个线程。即如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。
6.影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
7.执行过程:每个独立的进程有程序运行的入口、顺序执行序列和程序出口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制,两者均可并发执行
image.png2. 从 JVM 角度说进程和线程之间的关系(重要)
图解进程和线程的关系
下图是 Java 内存区域,通过下图我们从 JVM 的角度来说一下线程和进程之间的关系。
在这里插入图片描述从上图可以看出:一个进程中可以有多个线程,多个线程共享进程的堆和方法区 (JDK1.8 之后的元空间)资源,但是每个线程有自己的程序计数器、虚拟机栈 和 本地方法栈。
程序计数器为什么是私有的?
程序计数器主要有下面两个作用:
- 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。
- 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。
需要注意的是,如果执行的是 native 方法,那么程序计数器记录的是 undefined 地址,只有执行的是 Java 代码时程序计数器记录的才是下一条指令的地址。
所以,程序计数器私有主要是为了线程切换后能恢复到正确的执行位置。
虚拟机栈和本地方法栈为什么是私有的?
- 虚拟机栈:每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。
- 本地方法栈:和虚拟机栈所发挥的作用非常相似,区别是: 虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。
所以,为了保证线程中的局部变量不被别的线程访问到,虚拟机栈和本地方法栈是线程私有的。
一句话简单了解堆和方法区
堆和方法区是所有线程共享的资源,其中堆是进程中最大的一块内存,主要用于存放新创建的对象 (所有对象都在这里分配内存),方法区主要用于存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
多进程和多线程区别
多进程:操作系统中同时运行的多个程序
多线程:在同一个进程中同时运行的多个任务
举个例子,多线程下载软件,可以同时运行多个线程,但是通过程序运行的结果发现,每一次结果都不一致。 因为多线程存在一个特性:随机性。造成的原因:CPU在瞬间不断切换去处理各个线程而导致的,可以理解成多个线程在抢CPU资源。
多线程提高CPU使用率
image.png多线程并不能提高运行速度,但可以提高运行效率,让CPU的使用率更高。但是如果多线程有安全问题或出现频繁的上下文切换时,运算速度可能反而更低。
Java中的多线程
Java程序的进程里有几个线程:主线程,垃圾回收线程(后台线程)等
在 Java 中,当我们启动 main 函数时其实就是启动了一个 JVM 的进程,而 main 函数所在的线程就是这个进程中的一个线程,也称主线程。
Java支持多线程,当Java程序执行main方法的时候,就是在执行一个名字叫做main的线程,可以在main方法执行时,开启多个线程A,B,C,多个线程 main,A,B,C同时执行,相互抢夺CPU,Thread类是java.lang包下的一个常用类,每一个Thread类的对象,就代表一个处于某种状态的线程
CPU
CPU的概念:主责负责相关事情的判断以及实际处理的机制
总核数: 物理cpu个数每颗物理cpu的核数
总逻辑cpu个数:物理cpu个数每颗cpu的核数*超线程数
超线程
讲超线程概念之前,先来看个例子,选购电脑是,经常提到cpu是几核几线程。比如四核八线程,这几个参数的意思是:四核指的是cpu内核,是真时存在的物理内核,每个内核都相当于一颗单核cpu。线程是计算机程序执行的最小单元,每颗cpu核心在同一时间内只能处理一个线程。四核八线程则指的是支持超线程技术,可以把四个内核模拟出八个核心,这样在同一时间内可以并行处理八个线程,提高cpu的运算速度。
再举个例子:
我们可以把单核cpu工作理解成人在挑水:
当一个人拿一只桶提水,这是单核心线程单线程。
当一个人拿两只桶挑水时,相当于单核心双线程,支持超线程技术。
一个人挑两桶水不仅要有两只手,还需要两个桶,所以这就要要求操作系统和应用软件都支持超线程技术才能实现。
一个人挑两桶水不如两个人挑两桶水,所以单核双线程不如双核心cpu强大。综上所述,超线程就是利用cpu闲置资源的一种技术,虽然可以有效提高性能,但不如提高核心数强大。
那么什么是超线程呢?
概念: 利用特殊的硬件指令,把多线程处理器内部的两个逻辑内核(cpu)模拟成两个物理芯片(即在一个内核上也可以说是逻辑cpu上再模拟出两个逻辑cpu),减少闲置时间,提高cpu运行效率。
概念剖析:超线程技术是在一颗CPU同时执行多个程序而共同分享一颗CPU内的资源,理论上要像两颗CPU一样在同一时间执行两个线程,虽然采用超线程技术能同时执行两个线程,但它并不象两个真正的CPU那样,每个CPU都具有独立的资源。当两个线程都同时需要某一个资源时,其中一个要暂时停止,并让出资源,直到这些资源闲置后才能继续。因此超线程的性能并不等于两颗CPU的性能。
##总结:
1. 物理cpu是真实存在的,内核是属于物理cpu的核心,内核也是单核cpu,也叫逻辑cpu
2.超线程:在内核上模拟出的2个逻辑cpu即两个逻辑cpu模拟出的2个物理芯片
3.如何开启超线程? --》在bios里面去开启,找Hyper-Theading项,改为enabled
1.linux系统中查看CPU信息
在linux操作系统中,CPU的信息在启动的过程中被装载到虚拟目录/proc下的cpuinfo文件中,我们可以通过 cat /proc/cpuinfo 查看一下:
image.png
image.png
下面我们来分析其中几个比较重要的指标:
1.physical id : 物理CPU的标识符。物理CPU个数等于physical id的最大值加1 。
2.拥有相同physical id的所有逻辑处理器属于同一颗物理CPU
3.processor : 逻辑处理器的id。逻辑CPU个数,等于最大processor值加1
4.core id: 内核的id。每个core id 均代表一个唯一的处理器内核,所有带有相同core id 的逻辑CPU均位于同一处理器内核上
5.cpu cores : 位于相同物理封装的处理器中的内核数量
6.siblings : 位于相同物理封装的处理器中的逻辑处理器的数量。
上图cpu查看结果得出相关信息如下:
1.physical id 都为0,说明这台机器只有一个物理处理器;
2.processor有两个不同的编号,说明这台机器有2个逻辑CPU,并且同属于一个physical id
3.cpu cores 的值为2,说明CPU是双核心的,并且每个核心只有一个逻辑处理器(没有开启超线程)
4.siblings: 值为2,和cpu cores值相等,说明没有开启超线程
下面通过几个参数,加深理解:
image.png在这个服务器上,'cpu cores' 为4,physical id 有两个,core id有8个,siblings的值为8,总共有16个processor。
所以这个服务器主机的CPU为2个物理封装的处理器,每个处理器又有4个处理核心(cpu cores),每个cpu core有可划分为2个逻辑处理器(超线程技术),因此,每个物理处理器上有8个逻辑处理器,总共就有16个processor。这回明白了吧。大体的结构如下图:
image.png总结:
1.每个core id 均代表一个唯一的处理器内核,所有带有相同core id 的逻辑CPU均位于同一处理器内核上。
2、所以同一处理器内核上如果有一个以上逻辑CPU有用相同的core id和physical id ,则说明系统支持超线程(HT)技术。
3.如果有两个或两个以上的逻辑CPU拥有相同的physical id ,但是core id不同,则说明这是一个多内核处理器,cpu cores字段也可以表示是否支持多内核
2.通过参数获取cpu信息
(1)查看物理cpu的个数
[root@localhost /]# cat /proc/cpuinfo | grep "physical id" |sort|uniq|wc -l
2
(2) 查看每个物理cpu的核数
[root@localhost /]# cat /proc/cpuinfo | grep " cpu cores"|uniq
cpu cores : 4
(3)查看逻辑cpu的个数(逻辑CPU个数等于最大processor值加1)
[root@localhost /]# cat /proc/cpuinfo | grep "processor" | wc -l
8
(4)查看siblings数量:sblings位于相同物理封装的处理器中的逻辑处理器的数量
[root@localhost /]# grep "siblings" /proc/cpuinfo|uniq
8
如果“siblings”和“cpu cores”一致,则说明不支持超线程,或者超线程未打开。如果“siblings”是“cpu cores”的两倍,则说明支持超线程,并且超线程已打开。如果有两个逻辑CPU具有相同的”core id”,那么超线程是打开的
上述命令中涉及的参数讲解:(后面再补,这个不是重点)
(1)sort:排序
(2)uniq:删除重复行
(3)wc :统计文件里面有多少单词,多少行,多少字符
选项与参数:
-l :仅列出行;
-w :仅列出多少字(英文单字);
-m :多少字符
#wc -l /etc/passwd #统计行数,在对记录数时,很常用
40 /etc/passwd #表示系统有40个账户
#wc -w /etc/passwd #统计单词出现次数
45 /etc/passwd
#wc -m /etc/passwd #统计文件的字节数
1719
网友评论