详解进程和线程的区别

一、简单理解进程与线程


1.进程是操作系统进行资源分配和调度的一个基本单位。资源包括CPU、内存、磁盘等IO设备等等。每一个进程启动时都会最先产生一个线程,即主线程。然后主线程会再创建其他的子线程。


2.线程是一个基本的CPU执行单元。它必须依托于进程存活。一个线程是一个execution context(执行上下文),即一个CPU执行时所需要的一串指令。


举个简单的例子:电脑上同时运行的浏览器和视频播放器是两个不同的进程。进程可能包含多个子任务,这些子任务就是线程。比如视频播放器在播放视频时要同时显示图像、播放声音、显示字幕,可以理解为三个线程。

二、在Linux内核中实现方式的不同

在Linux 里面,无论是进程还是线程,到了内核里面,我们统一都叫任务(Task)。由一个统一的结构 task_struct 进行管理,这个task_struct 数据结构非常复杂,囊括了进程管理生命周期中的各种信息。

在Linux操作系统内核初始化时会创建第一个进程,即0号创始进程。随后会初始化1号进程(用户进程的第一个:/usr/lib/systemd/systemd),2号进程(内核进程的第一个:[kthreadd]),其后所有的进程线程都是在他们的基础上fork出来的。 

我们一般都是通过fork系统调用来创建新的进程。fork 系统调用包含两个重要的事件,一个是将 task_struct 结构复制一份并且初始化,另一个是试图唤醒新创建的子进程。

无论是进程还是线程,在内核里面都是task,但是,线程不是一个完全由内核实现的机制,它是由内核态和用户态合作完成的。创建进程的话,调用的系统调用是 fork,会将五大结构 files_struct、fs_struct、sighand_struct、signal_struct、mm_struct 都复制一遍,从此父进程和子进程各用各的数据结构。而创建线程的话,调用的是系统调用 clone,五大结构仅仅是引用计数加一,也即线程共享进程的数据结构。

 三、进程和线程的主要区别:

功能:

进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位。

开销:

每个进程都有独立的内存空间,存放代码和数据段等,程序之间的切换会有较大的开销。

线程可以看做轻量级的进程,线程之间共享内存空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销小。

运行环境:

在操作系统中能同时运行多个进程;而在同一个进程(程序)中有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行)

创建过程:

在创建新进程的时候,会将父进程的所有五大数据结构复制新的,形成自己新的内存空间数据,而在创建新线程的时候,则是引用进程的五大数据结构数据,但是线程会有自己的私有数据、栈空间。

执行过程:

每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

逻辑意义:

多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。

四、上下文切换具体指什么:

操作系统抽象出一个进程的概念,让应用程序专心于实现自己的业务逻辑既可,对应用程序屏蔽了CPU调度、内存管理等硬件细节,而且在有限的CPU上可以“同时”进行许多个任务。但是它为用户带来方便的同时,也引入了一些额外的开销。

在操作系统中,由于CPU的时间片调度策略,从一个进程切换到另一个进程需要保存当前进程的状态并恢复另一个进程的状态:当前运行任务转为就绪(或者挂起、删除)状态,另一个被选定的就绪任务成为当前任务。上下文切换包括保存当前任务的运行环境,恢复将要运行任务的运行环境。

在上下文切换过程中,CPU会停止处理当前运行的程序,并保存当前程序运行的具体位置以便之后继续运行。从这个角度来看,上下文切换有点像我们同时阅读几本书,在来回切换书本的同时我们需要记住每本书当前读到的页码。

在三种情况下可能会发生上下文切换:中断处理,多任务处理,内核/用户态切换

在中断处理中,其他程序”打断”了当前正在运行的程序。当CPU接收到中断请求时,会在正在运行的程序和发起中断请求的程序之间进行一次上下文切换。

在多任务处理中,CPU会在不同程序之间来回切换,每个程序都有相应的处理时间片,CPU在两个时间片的间隔中进行上下文切换。

在Linux中进行内核/用户态切换也会进行上下文切换,进行系统调用时,CPU寄存器里原来用户态的指令位置需要先保存起来。接着,为了执行内核态代码,CPU寄存器需要更新为内核态指令的新位置。最后才是跳转到内核态运行内核任务。而系统调用结束后,CPU寄存器需要恢复原来保存的用户态,然后再切换到用户空间,继续运行进程,所以一次系统调用的过程,其实是发生了两次CPU上下文切换。

CPU上下文切换,是保证Linux系统正常工作的核心功能之一,一般情况下不需要我们特别关注。

但过多的上下文切换,会把CPU时间消耗在寄存器、内核栈以及虚拟内存等数据的保存和恢复上,从而缩短进程真正运行的时间,导致系统的整体性能大幅下降。

#############################################################################

鸣谢:特别感谢所有在CSDN等网站热爱技术、乐于分享的工程师们。

说明:本文只是个人学习之用。

#############################################################################

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值