持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情
可以先从广义操作系统层面理解,进程是分配资源的基本单位,而线程是执行调度的基本单位。比方说一个QQ.exe程序,运行这个程序,操作系统就给他分配资源,这个资源很宽泛,包括但不局限于内存空间,CPU计算资源,寄存器等等,从而形成一个进程。再次运行一遍这个程序,操作系统又会重新起一个进程,虽然依然是分配资源,但是这个资源和前面的就是不一样的,不共享的,具体的来说就是两个进程拥有不同的地址空间,所以进程是分配资源的基本单位。而分配完资源后,CPU开始读取进程的指令,从main线程开始执行,后面执行什么程序,由CPU进行调度,所以说线程是CPU执行调度的基本单位。
以JVM为例子进行介绍,操作系统层面,JVM就是一个进程,而根据java程序的不同,它可能有多个线程,每个线程共享堆和方法区(1.8之后是元空间),每个线程私有程序计数器、JVM栈和本地方法栈,既然有共享区域,就决定了在并发情况下,同一个进程的线程会相互影响,但是不同的进程,由于他们没有共享空间,所以不会产生并发安全问题,但是既然线程有这个致命缺点,为什么还要诞生线程这个概念而不是继续优化进程呢?因为线程比进程更加轻量级,它又叫做轻量级进程,特别是在现在存在着大量计算和大量IO处理的环境下,线程这种轻量级进程的优势被凸显的淋漓尽致。
而从Linux内核角度来看,它并没有线程这个概念,Linux把所有的线程都当作进程来实现,只不过线程被是视为一个与其他进程共享某些资源(主要是内存地址空间)的进程,每个线程拥有唯一隶属于自己的task_struct,所以在内核中,它看起来就像是一个普通的进程。