1. 简介
用户打开浏览器,其实就是打开了浏览器应用程序。那么什么是程序呢?我们常说浏览器是多线程的,JS 是单线程的,那么什么是线程呢?说到线程,和我们常说的进程有什么关系?这两者和程序之间又是什么关系呢?
为了解答这些疑问,也为了更好地理解浏览器的工作原理,我们有必要先学习一下程序,进程和线程的概念。另外我们还需要了解并行与并发以及多核与多机的概念。当然,我们只是简单了解一下这些概念,如果想要深入研究,比如CPU的工作机制,需要向下看汇编与操作系统的知识,作为浅析阶段,这个系列肯定是不会涉及了。
js是单线程,如何实现异步?这种异步是不是并发?浏览器如何实现多线程开发?
2. 程序
2.1 程序的定义
程序描述计算机索要完成的具有独立功能的,并在时间上按严格次序前后相继的计算机操作序列的集合,是一个静态的概念。
2.2 程序的执行
程序的执行可以分为顺序执行和并发执行。
2.2.1 顺序执行
把一个具有独立功能的程序独占处理机直到最终结束的过程称为顺序执行。计算的CPU是通过时序脉冲来控制执行命令的。程序的顺序执行有以下特点:
顺序性
程序顺序执行时,其执行过程可看作一系列严格按照程序规定的状态转移过程,也就是每执行一条指令,系统将从上一个执行状态转移到下一个执行状态,且上一条指令的执行结束是下一条指令执行开始的充分条件。封闭性
程序执行的最终结果由给定的初始条件决定,不受外界因素影响。可再现性
程序执行的最终结果可再现。即,与执行速度无关,只有初始条件相同,则不论何时重复执行程序都会得到相同结果。
2.2.2 并发执行
程序的并发执行是为增加计算系统的处理能力和提高资源利用率所采用的一种同时操作技术。
分为两种:一种是多道程序系统的程序执行环境变化所引起的多道程序的并发执行,(资源有限,资源的共享与竞争)多道程序的并发执行在宏观上是同时进行的,但在微观上(也就是执行级上)仍是顺序执行(单核);一种是某道程序的几个程序段中包含着一部分可以同时执行或顺序颠倒执行的代码。
程序的并发执行总结为:一组在逻辑上互相独立的程序或程序段在执行过程中,其执行时间在客观上互相重叠。即,一个程序段的执行尚未结束,另一个程序段的执行已经开始的这种执行方式。
在许多情况下计算机需要能够同时处理多个具有独立功能的程序,其执行环境具有以下特点:
独立性
逻辑上独立,若资源充沛,每道程序都可以独立执行,执行速度与其他程序无关,起止时间也独立。随机性
程序和数据的输入和执行开始时间都是随机的。资源共享性
即包括硬件也包括软件。
程序并发执行的影响:
好处是充分地利用了系统资源,从而提高系统的处理能力;另一方面,由于资源共享和竞争,改变了程序的执行速度。一般情况下,并发执行的各程序段如果共享软、硬件资源,都会造成其执行结果其执行速度影响的局面(封闭性和可再现性),为了控制和协调各程序段执行过程中的软、硬件资源的共享和竞争,必须应该有一个描述各程序段执行过程和共享资源的基本单位,即,进程。
3. 进程
3.1 进程的定义
进程,是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竟争计算机系统资源的基本单位。每一个进程都有一个自己的地址空间,即进程空间。狭义上来理解,可以解释为正在运行的程序的实例(an instance of a computer program that is being executed)。
3.2 进程的特征
进程有如下特征:
动态性
进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。并发性
任何进程都可以同其他进程一起并发执行。独立性
进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位。异步性
由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进。结构特征
进程由程序、数据和进程控制块三部分组成。
3.3 进程的状态
一个进程的生命周期可以划分为一组状态,这些状态刻画了整个进程。进程状态即体现一个进程的生命状态,反映进程执行过程的变化。这些状态随着进程的执行和外界条件的变化而转换。在三态模型中,进程状态分为三个基本状态,即运行态,就绪态,阻塞态。在五态模型中,进程分为新建态、终止态,运行态,就绪态,阻塞态。
3.3.1 三态模型
一个进程从创建而产生至撤销而消亡的整个生命期间,有时占有处理器执行,有时虽可运行但分不到处理器、有时虽有空闲处理器但因等待某个事件的发生而无法执行,这一切都说明进程和程序不相同,它是活动的且有状态变化的,这可以用一组状态加以刻画。为了便于管理进程,一般来说,按进程在执行过程中的不同情况至少要定义三种不同的进程状态:
就绪(ready)态:进程具备运行条件,等待系统分配处理器以便运行。即进程已获得除CPU外的所有必要资源,只等待CPU时的状态。一个系统会将多个处于就绪状态的进程排成一个就绪队列。
运行(running)态:又译作执行态。进程占有处理器正在运行。即进程已获CPU,正在执行。单处理机系统中,处于执行状态的进程只一个;多处理机系统中,有多个处于执行状态的进程。
等待(wait)态:又称为阻塞(blocked)态或睡眠(sleep)态,指进程不具备运行条件,正在等待某个事件的完成。即正在执行的进程由于某种原因而暂时无法继续执行,便放弃处理机而处于暂停状态,即进程执行受阻。
通常,一个进程在创建后将处于就绪状态。每个进程在执行过程中,任意时刻当且仅当处于上述三种状态之一。同时,在一个进程执行过程中,它的状态将会发生改变。引起进程状态转换的具体原因如下:
- 运行态——等待态:等待使用资源或某事件发生,如等待外设传输,等待人工干预。
- 等待态——就绪态:资源得到满足或某事件己经发生,如外设传输结束,人工干预完成。
- 运行态——就绪态:运行时间片到,或出现有更高优先权进程。
- 就绪态——运行态:CPU空闲时被调度选中一个就绪进程执行。
三态的转换可以看以下两张图,意思其实是一样的:
3.3.2 五态模型
在一个实际的系统里进程的状态及其转换比上节叙述的复杂一些,例如,引入专门的新建态(new)和终止态(exit )。
新建(new)态:又译作创建态。新建态对应于进程刚刚被创建的状态,创建一个进程要通过两个步骤,首先,是为一个新进程创建PCB,并填写必要管理信息;然后,让该进程进入就绪态。此时进程将处于新建态,它并没有被提交执行,而是在等待操作系统完成创建进程的必要操作。必须指出的是,操作系统有时将根据系统性能或主存容量的限制推迟新建态进程的提交。
终止(exit)态:进程的终止也要通过两个步骤,首先,是等待操作系统进行善后;然后,退出主存。当一个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系统所终结,或是被其他有终止权的进程所终结,它将进入终止态。进入终止态的进程以后不再执行,但依然保留在操作系统中等待善后。一旦其他进程完成了对终止态进程的信息抽取之后,操作系统将删除该进程。
引起进程状态转换的具体原因如下:
- NULL——新建态: 执行一个程序,创建一个子进程。
- 新建态——就绪态: 当操作系统完成了进程创建的必要操作,并且当前系统的性能和内存的容量均允许。
- 运行态——终止态: 当一个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系统所终结,或是被其他有终止权的进程所终结。
- 终止态——NULL: 完成善后操作。
- 就绪态——终止态: 未在状态转换图中显示,但某些操作系统允许父进程终结子进程。
- 等待态——终止态: 未在状态转换图中显示,但某些操作系统允许父进程终结子进程。
五态的转换可以看下面这张图:
3.3.3 状态控制
进程创建
每个进程都有生命期,即从创建到消亡的时间周期。当操作系统为一个程序构造一个进程控制块并分配地址空间之后,就创建了一个进程。进程的创建来源于以下四个事件:
(1)提交个批处理作业。
(2)在终端上个交互式作业登录。
(3)操作系统创建‘个服务进程。
(4)存在的进程创建新的进程。进程的阻塞和唤醒
进程的阻塞是指使一个进程让出处理器,去等待一个事件,如等待资源、等待I/O完成、等待一个事件发生等,通常进程自己调用阻塞原语阻塞自己,所以,是进程自主行为,是一个同步事件。当一个等待事件结束会产生一个中断,从而,激活操作系统,在系统的控制之下将被阻塞的进程唤醒,如I/O操作结束、某个资源可用或期待事件出现。进程的阻塞和唤醒显然是由进程切换来完成。进程的撤销
一个进程完成了特定的工作或出现了严重的异常后,操作系统则收回它占有的地址空间和进程控制块,此时就说撤销了一个进程。进程撤销可以分正常和非正常撤销,前者如分时系统中的注消和批处理系统中的撤离作业步,后者如进程运行过程中出现错误与异常。进程的挂起和激活
当出现了引起挂起的事件时系统或进程利用挂起原语把指定进程或处于阻塞状态的进程挂起。其执行过程大致如下:检查要被挂起进程的状态,若处于活动就绪态就修改为挂起就绪,若处于阻塞态,则修改为挂起阻塞。被挂起进程PCB的非常驻部分要交换到磁盘对换区。
当系统资源尤其是内存资源充裕或进程请求激活指定进程时,系统或有关进程会调用激活原语把指定进程激活,该原语所做的主要工作是:把进程PCB非常驻部分调进内存,然后修改它的状态,挂起等待态改为等待态,挂起就绪态改为就绪态,并分别排入相应队列中。
可以参考下图:
3.4 进程和程序的区别和联系:
进程是一个动态概念,而程序是一个静态的概念。程序是指令的有序集合,没有任何执行的意义,而进程则强调执行过程,它动态被创建,并被调度执行消亡。
进程具有并发特点。进程具有并发特征的两个方面:独立性和异步性——不考虑资源的情况下,各进程的执行是独立的,速度是异步的,而程序没有并发特征。
进程是竞争计算系统资源的基本单位,从而其并发性受到系统自己的制约,这里,制约就是对程序独立性和异步性的限制。
一个程序可对应多个进程,也就是说同一程序同时运行于若干个数据集合上,它属于若干个不同的进程。但是程序并不能独立运行,作为资源分配和独立运行的基本单元都是进程。 一个进程可以对应多个程序。
一个更有意思的解释可以参考这篇文章:进程和程序(Process and Program)
4. 线程
4.1 线程的定义
线程的出现是为了降低上下文切换的消耗,提高系统的并发性,并突破一个进程只能干一样事的缺陷,使到进程内并发成为可能。
假设,一个文本程序,需要接受键盘输入,将内容显示在屏幕上,还需要保存信息到硬盘中。若只有一个进程,势必造成同一时间只能干一样事的尴尬(当保存时,就不能通过键盘输入内容)。若有多个进程,每个进程负责一个任务,进程A负责接收键盘输入的任务,进程B负责将内容显示在屏幕上的任务,进程C负责保存内容到硬盘中的任务。这里进程A,B,C间的协作涉及到了进程通信问题,而且有共同都需要拥有的东西——-文本内容,不停的切换造成性能上的损失。若有一种机制,可以使任务A,B,C共享资源,这样上下文切换所需要保存和恢复的内容就少了,同时又可以减少通信所带来的性能损耗,那就好了。是的,这种机制就是线程。
线程也叫轻量级进程,它是一个基本的CPU执行单元,也是程序执行过程中的最小单元,由线程ID、程序计数器、寄存器集合和堆栈共同组成。线程的引入减小了程序并发执行时的开销,提高了操作系统的并发性能。线程没有自己的系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。
4.2 线程的特征
在多线程OS中,通常是在一个进程中包括多个线程,每个线程都是作为利用CPU的基本单位,是花费最小开销的实体。线程具有以下属性。
轻型实体
线程中的实体基本上不拥有系统资源,只是有一点必不可少的、能保证独立运行的资源。
线程的实体包括程序、数据和TCB。线程是动态概念,它的动态特性由线程控制块TCB(Thread Control Block)描述。TCB包括以下信息:
(1)线程状态。
(2)当线程不运行时,被保存的现场资源。
(3)一组执行堆栈。
(4)存放每个线程的局部变量主存区。
(5)访问同一个进程中的主存和其它资源。
用于指示被执行指令序列的程序计数器、保留局部变量、少数状态参数和返回地址等的一组寄存器和堆栈。独立调度和分派的基本单位
在多线程OS中,线程是能独立运行的基本单位,因而也是独立调度和分派的基本单位。由于线程很“轻”,故线程的切换非常迅速且开销小(在同一进程中的)。可并发执行
在一个进程中的多个线程之间,可以并发执行,甚至允许在一个进程中所有线程都能并发执行;同样,不同进程中的线程也能并发执行,充分利用和发挥了处理机与外围设备并行工作的能力。共享进程资源
在同一进程中的各个线程,都可以共享该进程所拥有的资源,这首先表现在:所有线程都具有相同的地址空间(进程的地址空间),这意味着,线程可以访问该地址空间的每一个虚地址;此外,还可以访问进程所拥有的已打开文件、定时器、信号量机构等。由于同一个进程内的线程共享内存和文件,所以线程之间互相通信不必调用内核。
4.3 线程的状态
线程从创建、运行到结束总是处于下面五个状态之一:新建状态、就绪状态、运行状态、阻塞状态及死亡状态。
新建状态(New Thread)
产生一个Thread对象就生成一个新线程。当线程处于"新线程"状态时,仅仅是一个空线程对象,它还没有分配到系统资源。因此只能启动或终止它。任何其他操作都会引发异常。例如,一个线程调用了new方法之后,并在调用start方法之前的处于新线程状态,可以调用start和stop方法。就绪状态(Runnable)
start()方法产生运行线程所必须的资源,调度线程执行,并且调用线程的run()方法。在这时线程处于就绪状态。该状态不称为运行态是因为这时的线程并不总是一直占用处理机。特别是对于只有一个处理机的PC而言,任何时刻只能有一个处于就绪态的线程占用处理机。Java通过调度来实现多线程对处理机的共享。注意,如果线程处于Runnable状态,它也有可能不在运行,这是因为还有优先级和调度问题。运行状态(Running)
当线程获得CPU时间后,它才进入运行状态,真正开始执行run()方法。阻塞状态(Blocked)
所谓阻塞状态是正在运行的线程没有运行结束,暂时让出CPU,这时其他处于就绪状态的线程就可以获得CPU时间,进入运行状态。
阻塞状态分为三种:
1、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
2、同步阻塞:运行的线程在获取对象同步锁时,若该同步锁被别的线程占用,则JVM会把线程放入锁池中。
3、其他阻塞:运行的线程执行Sleep()方法,或者发出I/O请求时,JVM会把线程设为阻塞状态。当Sleep()状态超时、或者I/O处理完毕时,线程重新转入就绪状态。
线程运行过程中,可能由于各种原因进入阻塞状态:
①线程通过调用sleep方法进入睡眠状态;
②线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
③线程试图得到一个锁,而该锁正被其他线程持有;
④线程在等待某个触发条件;
具体来讲,线程被堵塞可能是由下述五个方法造成的:
(1) 调用sleep(毫秒数),使线程进入"睡眠"状态。在规定的时间内,这个线程是不会运行的。
(2) 用suspend()暂停了线程的执行。除非线程收到resume()消息,否则不会返回"可运行"状态。
(3) 用wait()暂停了线程的执行。除非线程收到nofify()或者notifyAll()消息,否则不会变成"可运行"(是的,这看起来同原因2非常相象,但有一个明显的区别是我们马上要揭示的)。
(4) 线程正在等候一些IO(输入输出)操作完成。
(5) 线程试图调用另一个对象的"同步"方法,但那个对象处于锁定状态,暂时无法使用。死亡状态(Dead)
当线程执行完run()方法中的代码,或别的线程调用stop()方法,或者遇到了未捕获的异常,就会退出run()方法,此时就进入死亡状态,该线程结束生命周期。通常Applet使用它的stop()方法来终止它产生的所有线程。
为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使用isAlive方法,如果是可运行或被阻塞,这个方法返回true;如果线程仍旧是new状态且不是可运行的,或者线程死亡了,则返回false。
可以参考下图:
详细地状态转换可以参考这里线程的几种状态转换。
4.4 线程和进程的关系和区别
进程和线程的关系:
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,至少有一个线程。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
(3)处理机分给线程,即真正在处理机上运行的是线程。
(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。线程是指进程内的一个执行单元,也是进程内的可调度实体.
进程与线程的区别:
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。
5. 多进程与多线程的选择
5.1并行与并发
并发处理(concurrency Processing):指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机(CPU)上运行,但任一个时刻点上只有一个程序在处理机(CPU)上运行。当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。这种方式我们称之为并发(Concurrent)。
并行:当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。并行处理(Parallel Processing)是计算机系统中能同时执行两个或更多个处理的一种计算方法。并行处理可同时工作于同一程序的不同方面。并行处理的主要目的是节省大型和复杂问题的解决时间。
并发的关键是你有处理多个任务的能力,不一定要同时。并行的关键是你有同时处理多个任务的能力。所以说,并行是并发的子集。
5.2 多核与多机
- 多处理机(SMP):
- 多个物理cpu
- 每个cpu有自己的独立cache、寄存器、运算单元。
- 每个cpu对内存的访问速度一样。
- 多核cpu (双核)
- 一个物理cpu包含多个cpu核心。
- 每个核心有自己的独立寄存器和运算单元。
- 可共享最后一级cache。
- 多线程cpu (双核四线程)
- 一个物理cpu包含多个逻辑cpu;这些逻辑cpu有自己的通用寄存器。
- 共享cache和运算单元(逻辑cpu)。
- 由于cpu通常包含多个运算单元,因此多线程cpu实际可同时运行。
5.3 多进程与多线程
5.3.1 多进程与多线程的优势对比
5.3.2进程之间,线程之间的通信方式以及优缺点
进程之间的通信:
1)管道
管道分为有名管道和无名管道
无名管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用.进程的亲缘关系一般指的是父子关系。无明管道一般用于两个不同进程之间的通信。当一个进程创建了一个管道,并调用fork创建自己的一个子进程后,父进程关闭读管道端,子进程关闭写管道端,这样提供了两个进程之间数据流动的一种方式。
有名管道也是一种半双工的通信方式,但是它允许无亲缘关系进程间的通信。
无名管道:
优点:简单方便;
缺点:1)局限于单向通信2)只能创建在它的进程以及其有亲缘关系的进程之间;3)缓冲区有限;
有名管道:
优点:可以实现任意关系的进程间的通信;
缺点:1)长期存于系统中,使用不当容易出错;2)缓冲区有限
2)信号量
信号量是一个计数器,可以用来控制多个线程对共享资源的访问.,它不是用于交换大批数据,而用于多线程之间的同步.它常作为一种锁机制,防止某进程在访问资源时其它进程也访问该资源.因此,主要作为进程间以及同一个进程内不同线程之间的同步手段.
优点:可以同步进程;
缺点:信号量有限
3)信号
信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生.
4)消息队列
消息队列是消息的链表,存放在内核中并由消息队列标识符标识.消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等特点.消息队列是UNIX下不同进程之间可实现共享资源的一种机制,UNIX允许不同进程将格式化的数据流以消息队列形式发送给任意进程.对消息队列具有操作权限的进程都可以使用msget完成对消息队列的操作控制.通过使用消息类型,进程可以按任何顺序读信息,或为消息安排优先级顺序.
优点:可以实现任意进程间的通信,并通过系统调用函数来实现消息发送和接收之间的同步,无需考虑同步问题,方便;
缺点:信息的复制需要额外消耗CPU的时间,不适宜于信息量大或操作频繁的场合
5)共享内存
共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问.共享内存是最快的IPC(进程间通信)方式,它是针对其它进程间通信方式运行效率低而专门设计的.它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步与通信.
优点:无须复制,快捷,信息量大;
缺点:1)通信是通过将共无法实现享空间缓冲区直接附加到进程的虚拟地址空间中来实现的,因此进程间的读写操作的同步问题;2)利用内存缓冲区直接交换信息,内存的实体存在于计算机中,只能同一个计算机系统中的诸多进程共享,不方便网络通信
6)套接字:可用于不同及其间的进程通信
优点:1)传输数据为字节级,传输数据可自定义,数据量小效率高;2)传输数据时间短,性能高;3) 适合于客户端和服务器端之间信息实时交互;4) 可以加密,数据安全性强
缺点:1) 需对传输的数据进行解析,转化成应用级的数据。
线程之间的通信方式:
- 锁机制:包括互斥锁、条件变量、读写锁
- 互斥锁提供了以排他方式防止数据结构被并发修改的方法。
- 读写锁允许多个线程同时读共享数据,而对写操作是互斥的。
- 条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。
- 信号量机制(Semaphore):包括无名线程信号量和命名线程信号量
- 信号机制(Signal):类似进程间的信号处理
线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。
5.3.3 多进程与多线程的选择
需要频繁创建销毁的优先用线程
原因请看上面的对比。
这种原则最常见的应用就是Web服务器了,来一个连接建立一个线程,断了就销毁线程,要是用进程,创建和销毁的代价是很难承受的需要进行大量计算的优先使用线程
所谓大量计算,当然就是要耗费很多CPU,切换频繁了,这种情况下线程是最合适的。
这种原则最常见的是图像处理、算法处理。强相关的处理用线程,弱相关的处理用进程
什么叫强相关、弱相关?理论上很难定义,给个简单的例子就明白了。
一般的Server需要完成如下任务:消息收发、消息处理。“消息收发”和“消息处理”就是弱相关的任务,而“消息处理”里面可能又分为“消息解码”、“业务处理”,这两个任务相对来说相关性就要强多了。因此“消息收发”和“消息处理”可以分进程设计,“消息解码”、“业务处理”可以分线程设计。
当然这种划分方式不是一成不变的,也可以根据实际情况进行调整。可能要扩展到多机分布的用进程,多核分布的用线程
原因请看上面对比。都满足需求的情况下,用你最熟悉、最拿手的方式
至于“数据共享、同步”、“编程、调试”、“可靠性”这几个维度的所谓的“复杂、简单”应该怎么取舍,我只能说:没有明确的选择方法。但我可以告诉你一个选择原则:如果多进程和多线程都能够满足要求,那么选择你最熟悉、最拿手的那个。
需要提醒的是:虽然有如此多选择与比较原则,但实际应用中基本上都是“进程+线程”的结合方式,千万不要真的陷入一种非此即彼的误区。
6. 小结
以上这些知识,其实是为了我们后续的讲解做铺垫,如果大家觉得很繁冗。可以归直接记住以下几点:
- 浏览器本身是一个程序,当我们运行它,操作学习通就开启了浏览器相关的进程。
- 浏览器进程里面包含了若干的线程。
- 一个核心同一时间只能处理一个线程,不过可以通过时间分片来实现多任务的并发,多核可以达成真正意义的并行。另外超线程技术通过逻辑CPU模拟核心达到并行,但是实际能力会弱于多核。
当然,作为一个前端开发者,你并不需要关心,你的线程会被分配给哪一个核心处理,这个会由操作系统根据一定算法进行调度。这些内容是为了下一阶段知识做铺垫而已,理解了这些,我们才能去探索为何我们说js是单线程的,但是却可以实现异步,在处理逻辑的时候还能进行请求操作等现象背后的原因。
参考
进程的概念
进程状态-百度百科
进程三种基本状态
进程五种基本状态
程序、进程和线程的关系
线程-百度百科
进程-百度百科
多线程—线程的5种状态
线程的基本概念、线程的基本状态以及状态之间的关系
多线程与多进程
进程与线程的区别-百度经验
进程和线程的区别以及联系
基础知识:线程,进程。多进程,多线程。并发,并行的区别
多处理机、多核cpu、多线程cpu的区别
多线程还是多进程的选择及区别
进程线程面试题总结
线程和进程的区别是什么?
进程上下文和中断上下文
多进程和多线程的优缺点
进程与线程的一个简单解释
深入理解javascript异步编程障眼法&&h5 web worker实现多线程
浅谈多核CPU、多线程与并行计算
处理器关于多核概念与区别 多核处理器工作原理及优缺点
对于多线程程序,单核cpu与多核cpu是怎么工作的
cpu个数、核数、线程数、Java多线程关系的理解
单核处理器、多核处理器、多处理器与多线程编程