CPU,进程, 线程的占用关系
并发和并行的概念区分:
并发,指的是多个事情,在同一时间段内同时发生了。
并行,指的是多个事情,在同一时间点上同时发生了。
并发的多个任务之间是互相抢占资源的。
并行的多个任务之间是不互相抢占资源的、
只有在多CPU或者一个CPU多核的情况中,才会发生并行。否则,看似同时发生的事情,其实都是并发执行的。
进程和线程的区别:
举一个例子:进程就相当于应用程序中的qq,而线程就是我在qq上做一个发送信息的一个任务线程。
进程是系统分配资源的基本单位,而线程则是进程的管理单位;进程是cpu,内存等资源占用的基本单位。一个进程至少包含一个执行线程。每个线程共享相同的地址空间,拥有自己独立的栈空间。
线程相比进程能减少开销,体现在:
1.线程的创建时间比进程快,因为进程在创建的过程中,还需要资源管理信息,比如内存管理信息、文件管理信息,而线程在创建的过程中,不会涉及这些资源管理信息,而是共享它们;
2.线程的终止时间比进程快,因为线程释放的资源相比进程少很多;
3.同一个进程内的线程切换比进程切换快,因为线程具有相同的地址空间(虚拟内存共享),这意味着同一个进程的线程都具有同一个页表,那么在切换的时候不需要切换页表。而对于进程之间的切换,切换的时候要把页表给切换掉,而页表的切换过程开销是比较大的;
4.由于同一进程的各线程间共享内存和文件资源,那么在线程之间数据传递的时候,就不需要经过内核了,这就使得线程之间的数据交互效率更高了;
所以,线程比进程不管是时间效率,还是空间效率都要高。
进程和线程的状态:
摘抄自java核心技术,觉得说的比较易懂,说明了多核或者单核cpu和线程,进程占用关系:
一旦一个线程开始运行,它不一定始终保持运行。事实上,运行中的线程有时需要暂停,让其他线程有机会运行。线程调度的细节依赖于操作系统提供的服务。抢占式调度系统给每一个可运行线程一个时间片(20-50ms)来执行任务。当时间片用完时,操作系统剥夺该线程的运行权,并给另一个线程一个机会来运行。当选择下一个线程时,操作系统会考虑线程的优先级。
现在所有的桌面以及服务器操作系统都使用抢占式调度。但是像手机这样的小型设备可能使用协助式调度。在这样的设备中,一个线程只有调用yield方法或被阻塞或等待时才会失去控制权。
在有多个处理器核心(多核单cpu)的机器上,每一个处理器运行一个线程,可以有多个线程并行运行。如果线程的数目多于处理器的数目,调度器还是需要分配时间片。
下面说一下cpu和进程和线程的上下文切换:
上下文切换是指cpu从一个进程或者线程切换到另一个进程或者线程。
概念:
CPU 寄存器和程序计数器是 CPU 在运行任何任务前,所必须依赖的环境,这些环境就叫做 CPU 上下文。
CPU 寄存器是 CPU 内部一个容量小,但是速度极快的内存(缓存),程序计数器则是用来存储 CPU 正在执行的指令位置、或者即将执行的下一条指令位置,意思就是这个线程或者进程进行到什么地方,记录下来。
CPU 上下文切换过程:就是先把前一个任务的 CPU 上下文(CPU 寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。之前的进程或者线程就会进入就绪状态队列,等待操作系统的调度,这个队列是用链表来进行。(如果调度系统将此线程或者进程的状态改变,则此数据将插入到其他状态的队列中。选用链表的原因是因为可能面临进程创建,销毁等调度导致进程状态发生变化,所以链表能够更加灵活的插入和删除。)
系统内核会存储保持下来的上下文信息,当此任务再次被分配给 CPU 运行时,CPU 会重新加载这些上下文,这样就能保证任务原来的状态不受影响,让任务看起来还是连续运行。
进程的上下文切换开销和线程的上下文切换开销对比:
进程切换:进程的上下文切换不仅包含了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的资源。
线程的切换:这还得看线程是不是属于同一个进程:
当两个线程不是属于同一个进程,则切换的过程就跟进程上下文切换一样;
当两个线程是属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据;
所以,线程的上下文切换相比进程,开销要小很多。
发生进程上下文切换有哪些场景?
为了保证所有进程可以得到公平调度,CPU 时间被划分为一段段的时间片,这些时间片再被轮流分配给各个进程。这样,当某个进程的时间片耗尽了,进程就从运行状态变为就绪状态,系统从就绪队列选择另外一个进程运行;
进程在系统资源不足(比如内存不足)时,要等到资源满足后才可以运行,这个时候进程也会被挂起,并由系统调度其他进程运行;
当进程通过睡眠函数 sleep 这样的方法将自己主动挂起时,自然也会重新调度;
当有优先级更高的进程运行时,为了保证高优先级进程的运行,当前进程会被挂起,由高优先级进程来运行;
发生硬件中断时,CPU 上的进程会被中断挂起,转而执行内核中的中断服务程序;
发生上下文切换的操作系统调度
在进程的生命周期中,当进程从一个运行状态到另外一状态变化的时候,其实会触发一次调度,调度有操作系统来出发,cpu来执行任务。
调度的原则:
-
CPU 利用率:调度程序应确保 CPU 是始终匆忙的状态,这可提高 CPU 的利用率;
-
系统吞吐量:吞吐量表示的是单位时间内 CPU 完成进程的数量,长作业的进程会占用较长的 CPU 资源,因此会降低吞吐量,相反,短作业的进程会提升系统吞吐量;
-
周转时间:周转时间是进程运行和阻塞时间总和,一个进程的周转时间越小越好;
-
等待时间:这个等待时间不是阻塞状态的时间,而是进程处于就绪队列的时间,等待的时间越长,用户越不满意;
-
响应时间:用户提交请求到系统第一次产生响应所花费的时间,在交互式系统中,响应时间是衡量调度算法好坏的主要标准。
这么多调度原则,目的就是要使得进程要「快」。
调度算法分为两类:
非抢占式调度算法挑选一个进程,然后让该进程运行直到被阻塞,或者直到该进程退出,才会调用另外一个进程,也就是说不会理时钟中断这个事情。
抢占式调度算法挑选一个进程,然后让该进程只运行某段时间,如果在该时段结束时,该进程仍然在运行时,则会把它挂起,接着调度程序从就绪队列挑选另外一个进程。这种抢占式调度处理,需要在时间间隔的末端发生时钟中断(一个时间片大约是20-50ms),以便把 CPU 控制返回给调度程序进行调度,也就是常说的时间片机制。
参考链接:https://xie.infoq.cn/article/8e66fa7ebe4d310db95b39c31
https://xie.infoq.cn/article/fccf4cc4523aba603525bbb37