海口网站运营托管咨询,做滤芯的网站,网站建设技术问题,wordpress自动博客什么是进程#xff1f;
我们都知道计算机的核心是CPU#xff0c;它承担了所有的计算任务#xff1b;而操作系统是计算机的管理者#xff0c;它负责任务的调度、资源的分配和管理#xff0c;统领整个计算机硬件#xff1b;应用程序则是具有某种功能的程序#xff0c;程序…什么是进程
我们都知道计算机的核心是CPU它承担了所有的计算任务而操作系统是计算机的管理者它负责任务的调度、资源的分配和管理统领整个计算机硬件应用程序则是具有某种功能的程序程序是运行于操作系统之上的。
进程的概念 进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程是操作系统进行资源分配和调度的一个独立单位是应用程序运行的载体。 进程是一种抽象的概念从来没有统一的标准定义。
进程一般由程序、数据集合和进程控制块三部分组成。
程序用于描述进程要完成的功能是控制进程执行的指令集数据集合是程序在执行时所需要的数据和工作区程序控制块(Program Control Block简称PCB)包含进程的描述信息和控制信息是进程存在的唯一标志。
进程具有的特征
动态性进程是程序的一次执行过程是临时的有生命期的是动态产生动态消亡的并发性任何进程都可以同其他进程一起并发执行独立性进程是系统进行资源分配和调度的一个独立单位结构性进程由程序、数据和进程控制块三部分组成。
什么是线程
在早期的操作系统中并没有线程的概念进程是能拥有资源和独立运行的最小单位也是程序执行的最小单位。任务调度采用的是时间片轮转的抢占式调度方式而进程是任务调度的最小单位每个进程有各自独立的一块内存使得各个进程之间内存地址相互隔离。
后来随着计算机的发展对CPU的要求越来越高进程之间的切换开销较大已经无法满足越来越复杂的程序的要求了。于是就发明了线程。
线程的概念 线程是程序执行中一个单一的顺序控制流程是程序执行流的最小单元是处理器调度和分派的基本单位。一个进程可以有一个或多个线程各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的线程由线程ID、当前指令指针(PC)、寄存器和堆栈组成。而进程由内存空间(代码、数据、进程空间、打开的文件)和一个或多个线程组成。 如上图在任务管理器的进程一栏里有道词典和有道云笔记就是进程而在进程下又有着多个执行不同任务的线程。
什么是任务调度
线程是什么
要理解这个概念需要先了解一下操作系统的一些相关概念。大部分操作系统(如Windows、Linux)的任务调度是采用时间片轮转的抢占式调度方式。
在一个进程中当一个线程任务执行几毫秒后会由操作系统的内核负责管理各个任务进行调度通过硬件的计数器中断处理器让该线程强制暂停并将该线程的寄存器放入内存中通过查看线程列表决定接下来执行哪一个线程并从内存中恢复该线程的寄存器最后恢复该线程的执行从而去执行下一个任务。
上述过程中任务执行的那一小段时间叫做时间片任务正在执行时的状态叫运行状态被暂停的线程任务状态叫做就绪状态意为等待下一个属于它的时间片的到来。
这种方式保证了每个线程轮流执行由于CPU的执行效率非常高时间片非常短在各个任务之间快速地切换给人的感觉就是多个任务在“同时进行”这也就是我们所说的并发(别觉得并发有多高深它的实现很复杂但它的概念很简单就是一句话多个任务同时执行)。多任务运行过程的示意图如下
操作系统中的任务调度
进程与线程的区别
前面讲了进程与线程但可能你还觉得迷糊感觉他们很类似。的确进程与线程有着千丝万缕的关系下面就让我们一起来理一理
线程是程序执行的最小单位而进程是操作系统分配资源的最小单位一个进程由一个或多个线程组成线程是一个进程中代码的不同执行路线进程之间相互独立但同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号)某进程内的线程在其它进程不可见调度和切换线程上下文切换比进程上下文切换要快得多。
线程与进程关系的示意图
进程与线程的资源共享关系
单线程与多线程的关系
总之线程和进程都是一种抽象的概念线程是一种比进程更小的抽象线程和进程都可用于实现并发。
在早期的操作系统中并没有线程的概念进程是能拥有资源和独立运行的最小单位也是程序执行的最小单位。它相当于一个进程里只有一个线程进程本身就是线程。所以线程有时被称为轻量级进程(Lightweight ProcessLWP。 早期的操作系统只有进程没有线程
后来随着计算机的发展对多个任务之间上下文切换的效率要求越来越高就抽象出一个更小的概念——线程一般一个进程会有多个(也可是一个)线程。
线程的出现使得一个进程可以有多个线程
什么是多线程与多核
上面提到的时间片轮转的调度方式说一个任务执行一小段时间后强制暂停去执行下一个任务每个任务轮流执行。很多操作系统的书都说“同一时间点只有一个任务在执行”。那有人可能就要问双核处理器呢难道两个核不是同时运行吗
其实“同一时间点只有一个任务在执行”这句话是不准确的至少它是不全面的。那多核处理器的情况下线程是怎样执行呢
这就需要了解内核线程。
多核(心)处理器是指在一个处理器上集成多个运算核心从而提高计算能力也就是有多个真正并行计算的处理核心每一个处理核心对应一个内核线程。
内核线程Kernel ThreadKLT就是直接由操作系统内核支持的线程这种线程由内核来完成线程切换内核通过操作调度器对线程进行调度并负责将线程的任务映射到各个处理器上。一般一个处理核心对应一个内核线程比如单核处理器对应一个内核线程双核处理器对应两个内核线程四核处理器对应四个内核线程。
现在的电脑一般是双核四线程、四核八线程是采用超线程技术将一个物理处理核心模拟成两个逻辑处理核心对应两个内核线程所以在操作系统中看到的CPU数量是实际物理CPU数量的两倍如你的电脑是双核四线程打开“任务管理器\性能”可以看到4个CPU的监视器四核八线程可以看到8个CPU的监视器。 双核四线程在Windows8下查看的结果
超线程技术就是利用特殊的硬件指令把一个物理芯片模拟成两个逻辑处理核心让单个处理器都能使用线程级并行计算进而兼容多线程操作系统和软件减少了CPU的闲置时间提高的CPU的运行效率。这种超线程技术(如双核四线程)由处理器硬件的决定同时也需要操作系统的支持才能在计算机中表现出来。
程序一般不会直接去使用内核线程而是去使用内核线程的一种高级接口——轻量级进程Lightweight ProcessLWP轻量级进程就是我们通常意义上所讲的线程也被叫做用户线程。由于每个轻量级进程都由一个内核线程支持因此只有先支持内核线程才能有轻量级进程。用户线程与内核线程的对应关系有三种模型一对一模型、多对一模型、多对多模型在这以4个内核线程、3个用户线程为例对三种模型进行说明。
一对一模型
对于一对一模型来说一个用户线程就唯一地对应一个内核线程(反过来不一定成立一个内核线程不一定有对应的用户线程)。这样如果CPU没有采用超线程技术(如四核四线程的计算机)一个用户线程就唯一地映射到一个物理CPU的内核线程线程之间的并发是真正的并发。一对一模型使用户线程具有与内核线程一样的优点一个线程因某种原因阻塞时其他线程的执行不受影响此处一对一模型也可以让多线程程序在多处理器的系统上有更好的表现。
但一对一模型也有两个缺点
许多操作系统限制了内核线程的数量因此一对一模型会使用户线程的数量受到限制许多操作系统内核线程调度时上下文切换的开销较大导致用户线程的执行效率下降。
多对一模型
多对一模型将多个用户线程映射到一个内核线程上线程之间的切换由用户态的代码来进行系统内核感受不到线程的实现方式。用户线程的建立、同步、销毁等都在用户态中完成不需要内核的介入。因此相对一对一模型多对一模型的线程上下文切换速度要快许多此外多对一模型对用户线程的数量几乎无限制。
但多对一模型也有两个缺点
如果其中一个用户线程阻塞那么其它所有线程都将无法执行因为此时内核线程也随之阻塞了在多处理器系统上处理器数量的增加对多对一模型的线程性能不会有明显的增加因为所有的用户线程都映射到一个处理器上了。
多对多模型
多对多模型结合了一对一模型和多对一模型的优点将多个用户线程映射到多个内核线程上。由线程库负责在可用的可调度实体上调度用户线程这使得线程的上下文切换非常快因为它避免了系统调用。但是增加了复杂性和优先级倒置的可能性以及在用户态调度程序和内核调度程序之间没有广泛且高昂协调的次优调度。
多对多模型的优点有
一个用户线程的阻塞不会导致所有线程的阻塞因为此时还有别的内核线程被调度来执行多对多模型对用户线程的数量没有限制在多处理器的操作系统中多对多模型的线程也能得到一定的性能提升但提升的幅度不如一对一模型的高。
在现在流行的操作系统中大都采用多对多的模型。
如何查看进程与线程
一个应用程序可能是多线程的也可能是多进程的如何查看呢在Windows下我们只须打开任务管理器就能查看一个应用程序的进程和线程数。按“CtrlAltDel”或右键快捷工具栏打开任务管理器。
如何查看线程数和进程数
在“进程”选项卡下我们可以看到一个应用程序包含的线程数。如果一个应用程序有多个进程我们能看到每一个进程如在上图中Google的Chrome浏览器就有多个进程。同时如果打开了一个应用程序的多个实例也会有多个进程如上图中我打开了两个cmd窗口就有两个cmd进程。如果看不到线程数这一列可以再点击“查看\选择列”菜单增加监听的列。
如何查看CPU和内存的使用率
在性能选项卡中我们可以查看CPU和内存的使用率根据CPU使用记录的监视器的个数还能看出逻辑处理核心的个数如我的双核四线程的计算机就有四个监视器。
如何查看CPU和内存的使用率
线程的生命周期
当线程的数量小于处理器的数量时线程的并发是真正的并发不同的线程运行在不同的处理器上。但当线程的数量大于处理器的数量时线程的并发会受到一些阻碍此时并不是真正的并发因为此时至少有一个处理器会运行多个线程。
在单个处理器运行多个线程时并发是一种模拟出来的状态。操作系统采用时间片轮转的方式轮流执行每一个线程。现在几乎所有的现代操作系统采用的都是时间片轮转的抢占式调度方式如我们熟悉的Unix、Linux、Windows及macOS等流行的操作系统。
我们知道线程是程序执行的最小单位也是任务执行的最小单位。在早期只有进程的操作系统中进程有五种状态创建、就绪、运行、阻塞(等待)、退出。早期的进程相当于现在的只有单个线程的进程那么现在的多线程也有五种状态现在的多线程的生命周期与早期进程的生命周期类似。
早期进程的生命周期
进程在运行过程有三种状态就绪、运行、阻塞创建和退出状态描述的是进程的创建过程和退出过程。
创建进程正在创建还不能运行。操作系统在创建进程时要进行的工作包括分配和建立进程控制块表项、建立 资源表格并分配资源、加载程序并建立地址空间就绪时间片已用完此线程被强制暂停等待下一个属于它的时间片到来运行此线程正在执行正在占用时间片阻塞也叫等待状态等待某一事件(如IO或另一个线程)执行完退出进程已结束所以也称结束状态释放操作系统分配的资源。
线程的生命周期
创建一个新的线程被创建等待该线程被调用执行就绪时间片已用完此线程被强制暂停等待下一个属于它的时间片到来运行此线程正在执行正在占用时间片阻塞也叫等待状态等待某一事件(如IO或另一个线程)执行完退出一个线程完成任务或者其他终止条件发生该线程终止进入退出状态退出状态释放该线程所分配的资源。
什么是协程 协程英文Coroutines是一种基于线程之上但又比线程更加轻量级的存在这种由程序员自己写程序来管理的轻量级线程叫做『用户空间线程』具有对内核来说不可见的特性。 因为是自主开辟的异步任务所以很多人也更喜欢叫它们纤程Fiber或者绿色线程GreenThread。正如一个进程可以拥有多个线程一样一个线程也可以拥有多个协程。
协程的目的
在传统的J2EE系统中都是基于每个请求占用一个线程去完成完整的业务逻辑包括事务。所以系统的吞吐能力取决于每个线程的操作耗时。如果遇到很耗时的I/O行为则整个系统的吞吐立刻下降因为这个时候线程一直处于阻塞状态如果线程很多的时候会存在很多线程处于空闲状态等待该线程执行完才能执行造成了资源应用不彻底。
最常见的例子就是JDBC它是同步阻塞的这也是为什么很多人都说数据库是瓶颈的原因。这里的耗时其实是让CPU一直在等待I/O返回说白了线程根本没有利用CPU去做运算而是处于空转状态。而另外过多的线程也会带来更多的ContextSwitch开销。
对于上述问题现阶段行业里的比较流行的解决方案之一就是单线程加上异步回调。其代表派是node.js以及Java里的新秀Vert.x。
而协程的目的就是当出现长时间的I/O操作时通过让出目前的协程调度执行下一个任务的方式来消除ContextSwitch上的开销。
协程的特点
线程的切换由操作系统负责调度协程由用户自己进行调度因此减少了上下文切换提高了效率。 线程的默认Stack大小是1M而协程更轻量接近1K。因此可以在相同的内存中开启更多的协程。 由于在同一个线程上因此可以避免竞争关系而使用锁。 适用于被阻塞的且需要大量并发的场景。但不适用于大量计算的多线程遇到此种情况更好实用线程去解决。 协程的原理 当出现IO阻塞的时候由协程的调度器进行调度通过将数据流立刻yield掉主动让出并且记录当前栈上的数据阻塞完后立刻再通过线程恢复栈并把阻塞的结果放到这个线程上去跑这样看上去好像跟写同步代码没有任何差别这整个流程可以称为coroutine而跑在由coroutine负责调度的线程称为Fiber。比如Golang里的 go关键字其实就是负责开启一个Fiber让func逻辑跑在上面。
由于协程的暂停完全由程序控制发生在用户态上而线程的阻塞状态是由操作系统内核来进行切换发生在内核态上。
因此协程的开销远远小于线程的开销也就没有了ContextSwitch上的开销。
协程和线程的比较
比较项线程协程占用资源初始单位为1MB,固定不可变初始一般为 2KB可随需要而增大调度所属由 OS 的内核完成由用户完成切换开销涉及模式切换(从用户态切换到内核态)、16个寄存器、PC、SP…等寄存器的刷新等只有三个寄存器的值修改 - PC / SP / DX.性能问题资源占用太高频繁创建销毁会带来严重的性能问题资源占用小,不会带来严重的性能问题数据同步需要用锁等机制确保数据的一直性和可见性不需要多线程的锁机制因为只有一个线程也不存在同时写变量冲突在协程中控制共享资源不加锁只需要判断状态就好了所以执行效率比多线程高很多。