[Linux]——Linux线程基本概念

线程

在这篇博客之前,我们已经介绍了Linux进程中大部分的概念,之前我们介绍过了进程的基本概念,进程的控制,信号,进程间通信等一系列的机制。而今天我们所要讲解的是Linux下线程的概念,就算有的同学可能还没有学习线程,但我们发现他经常与进程联系在一起,那么线程到底是什么呢?一起往下看。

什么是线程?

相信你应该还记得什么是进程吧,提到进程我们又不得不提程序这一概念,程序其实我们可以简单的理解为:他是一个普通的文件,是机器指令和数据的集合,这些指令和数据是磁盘上的一个可执行映像。这么说你可能觉得烧脑,那么我们换一种说法,不如说程序就是你期望完成工作的计划与步骤,他现在仅仅浮现在纸面上。所以进程的概念也就变的清晰明了,他是程序的一个执行实例,是为了完成我们的计划的动态实体。操作系统为了描述这个动态的实体不得不使用一些额外的数据(进程pcb,寄存器的值等),这些多出来为了管理进程的数据也就成了进程与程序间的根本区别点。所以你一定听过:进程是承担分配系统资源的基本实体

但是这和我们今天要说的线程有什么关系么?当然有,我们先来看看下面的一幅图:对于这幅图你应该不是很陌生,在操作系统创建出一个进程时必须创建其对应的进程PCB,mm_struct,页表中存放虚拟内存与物理内存的映射关系。
在这里插入图片描述
我们现在来看另一幅图来先大概让大家对线程有一个基本的认识:我们从图中发现,此时并不像上图那样一个pcb指向一个程序地址空间,而是多个pcb指向一个地址空间,这样也就意味着这些pcb共享一个进程地址空间,但是在cpu眼中依然看到的是一个个的pcb,所以cpu在下图中认为有3个进程,对他们进行调度,由于这三个pcb共享一个进程地址空间,相对于传统的进程来说就变得非常轻量化,有时候也说粒度小。我们将这样的轻量级进程称为线程,线程在进程内部执行,本质是在地址空间内运行
在这里插入图片描述
现在请你记住一句话:进程是承担分配系统资源的基本实体,而线程是调度的基本单位。 我们应该怎么理解呢?此时当我们再次提到进程应该明白,一个进程拥有一组pcb,一个进程地址空间,页表以及各种映射关系,这一整套东西强调的是他是一个占用资源的实体。而线程是进程内部的一个执行流。

那么我们怎么理解之前的进程,其实之前的进程我们就可以理解为内部只有一个线程执行流的单线程进程。这里有一个非常重要的点,我们都知道操作系统要进行管理就要先描述在组织,所以之前我们说操作系统管理进程时使用一个pcb结构体进行管理,而现在我们发现他在描述管理线程时同样也使用了pcb,并没有像其他平台一样使用一个tcb。只是创建一个线程时就创建一个新的pcb指向对应的进程地址空间,这里我们提炼出了一个非常重要的点,Linux平台下其实并没有真正意义上的线程,线程其实是用进程来模拟的,就如我们上面所说的,你可以将线程理解为一个轻量级进程,这样在cpu眼中虽然看到的都是进程,但是这种轻量级进程往往构建管理的代价比我们之前单线程的进程要小的多。

所以也就说明,当你站在cpu的角度来看,他的眼中看到的都是进程,而实际上有可能是线程,也有可能是进程。
在这里插入图片描述
我们对线程进行了如下的总结:

  • 在程序中的一个执行路线叫做线程。更准确的定义是:线程是进程内部的一个执行序列
  • 一切进程至少有一个执行线程
  • 线程在进程内部执行,本质在进程地址空间内执行
  • 在linux系统中,cpu眼中看到的pcb都要比传统的进程更加轻量化
  • 透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流

线程的优点

经过我们上面的讲解,相信你对线程现在有了初步的认识,既然我们上面一直强调他是一种轻量级进程,那么说明他一定有很多优点。

  • 创建一个新线程的代价要比创建一个新进程的代价要小的多,这点不难理解,因为多个线程共享一份资源,所以占用操作系统的资源就会变少
  • 与进程相比,线程之间的切换要比进程简单的多,因为当操作系统在对不同的进程进行切换时要切换他们的进程地址空间,页表等信息,而线程却不需要切换
  • 能充分的利用多处理器的可并行数量
  • 在等待慢速IO的操作结束的同时,程序可以执行其他的计算任务
  • 计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现
  • IO密集型,为了提高性能,将IO操作重叠。线程可以同时等待不同的IO操作

这里计算密集型是指程序中充满大量计算的程序,而IO密集型是指程序要经常发生IO操作,但是其实线程主要的优点还是创建代价的减小和线程切换的代价减小

线程的缺点

虽然线程的出现带来了很多优点,但是俗话说的好,事物都是有两面性的,那么一起来看看线程有哪些缺点:

  • 健壮性降低:我们上面一直在强调线程是进程内部的一个执行流,线程与进程不相同的是,进程运行时具有独立性,如果子进程由于某种错误或者异常退出,此时并不影响父进程,这也是为什么我们生活中微博挂掉而qq不会退出的原因,但是线程不一样,如果某个线程出现了异常,那么会导致整个进程退出。
  • 缺乏访问控制:线程共享进程的资源,所以这些资源被称为临界资源,如果我们对这些临界资源没有正确的访问控制,那么将可能产生不可预知的后果
  • 编程难度提高:上面种种缺点最后都会导致程序员在编写多线程程序时难度大大的提高,稍不留神就会出现线程异常的问题

Linux进程 Vs Linux线程

无论走到哪里,别人怎么问你,你始终要记住进程是承担分配系统资源的基本实体,而线程是调度的基本单位这句话。他们的区别就是围绕这句话展开的。

那么这里我们来谈一谈从资源上,线程和进程哪些资源是共享的,哪些资源是独立的。

共享资源:文件描述符,每种信号的处理机制,当前工作的目录,用户id和组id,代码和数据
独立资源:线程ID,一组寄存器(因为线程要被调度,所以他需要记录硬件上下文),自己的栈结构,调度优先级,信号屏蔽字

在这里插入图片描述

加深记忆小栗子

有的同学可能还是觉得线程是一个抽象的东西,那么这里举一个栗子你就能深刻理解线程与进程:

  • 我们都知道我们国家分配资源是以家庭为单位,所以你的家庭就是承担国家分配资源的实体,类比为进程。而你们家庭中的每一个人都是一个线程,你的家庭中冰箱,洗衣机,电视都是共享的资源,所以你们可以共同使用(代码数据)。但是你也有自己的小秘密(栈结构等),如果你家中有一个生了重病,那么就有可能导致整个家庭倾家荡产(线程异常),你们每一个人努力工作(调度)其实都是为了这个家庭更好,而你隔壁邻居家失窃而与你的家庭并没有什么关系(进程间独立性)。

总结

本篇博客重在让大家理解什么是线程,线程的特点以及其优缺点,往往线程的出现会与进程进行比较,这里一定要清楚我们始终强调的那句话,线程是cpu的调度单位,而进程是承担系统分配资源的一个实体,之后所有的特点都是以这句话展开。在清楚线程的概念之后,下篇博客我们将介绍线程的控制。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值