Linux讲解 进程线程
分类:
文章
•
2024-03-18 22:53:16
我们之前在Linux中引入了进程的概念,今天我们就在仔细的分析一下什么是进程,什么是线程,进程和线程之间有什么关系。
现在有两个程序一个是小红,一个是小蓝。
在计算机发展初期的时候,CPU是一个很稀缺的资源,他们两个必须轮流使用,只有小红执行结束之后,让出CPU,小蓝才能从头开始运行。人们把这种方式叫做批处理。
慢慢的,随着计算机的不断发展,CPU的处理能力越来越快了,已经远远的超过了内存和硬盘等硬件的读取速度,人们就发现这批处理的效果实在是太差了,CPU在执行小红程序的过程中,会去读取我们的内存和硬盘但是他们的速度实在是太慢了,这一大段时间CPU完全就没有工作,这时候完全可以让小蓝来运行一下子。但是这里必须要保证的是,你需要让CPU“记住”小红运行到哪里了,也就是必须保存好小红的执行现场。例如执行到哪一步了,下一条指令该是哪个了,现在CPU寄存器中的值都是些什么等等。不然等CPU让给小蓝之后再回来执行小红的时候,就没办法从刚刚中断的地方继续开始执行了。
这个来存储这个执行现场和小红的代码组成起来的结构体就是PCB,也就是我们常说的进程。小红和小蓝两个程序都被改造成了进程。并且还规定,他们两个谁都不能太长时间占据CPU,必须雨露均沾,每个只能在CPU执行一段时间然后就切换到另一个进程。
小红就很纳闷了,这样的话,那岂不是用户体验很不好,那在我的主人看来,我岂不是运行一会停一会,运行一会停一会。CPU就说了,你想错了,我的执行速度是超快的,虽然你们两个是在不停的切换,但是人类的眼睛根本没办法看出来的。这就是并发。因为在人类看起来他们两个就是在同时运行的,但是发展到现在进程已经实现了真正意义上的并行,因为现在的CPU已经是多核的了,不同的进程可能会被分配到不同的CPU内核上同时执行。
后来随着网络的发展,小红和小蓝已经能够连接互联网了,小红每次在访问互联网的时候就必须把CPU让给小蓝,因为访问互联网这是一个十分耗时的过程,有时候即使,小蓝已经执行结束了,CPU又给了小红,小红还是在等待网络数据的放回,她就必须在这里等着,什么也干不了。在人来看来他就卡死在这里了,一直没有响应。小红就问小蓝了,为什么咱们两个都是连接网络的操作,你就不会被卡死呢?
小强说,愚蠢!你的内部只有一个执行的流程,一旦遇到耗时的操作就得等着, 没有别的办法,而我内部搞了几个执行流程,也就是我们说的线程,一个用来获取网络数据,一个来处理其他信息,当我获取网络数据的线程正在操作的时候,就让操作系统来调用我的另一个线程,这样起码看起来我的其他任务没有耽误,没被卡死。
后来小红也采用了这样的办法, 也就是我们的进程中至少有一个主线程来执行过程,当然也可以再重新创建新的线程去执行新的东西。所以我们常说线程使我们的最小调度单位。
通俗来说线程就是一个轻量级的进程,是进程中的一个执行流,一个进程中至少有一个线程,Linux下线程是以进程pcb来模拟的,Linux下的pcb实际上就是一个线程的描述,Linux下的进程就变成了一个线程组。
线程主要有以下特点:
-
一般来说同一进程中的线程都是使用的都是同一片虚拟地址空间,因此线程间切换调度的成本要比进程切换的成本要低。
-
线程的创建和销毁成本也是要低于进程的。线程占用的资源要比进程少很多
-
在等待程序其他慢操作的时候,还可以执行程序的其他部分
-
因为他们共享了整个进程的代码段和数据段所以线程间通信更加方便。
-
但是常常来说一些系统调用或者异常都是针对进程的,如果进程中某个线程出现了问题,那么整个线程都会受到影响,所以线程的安全性相对较低。
-
因为线程之间共享了数据,方便了通信但是对资源的争抢处理就变的更难一些。
-
每个线程都是有自己的栈区的,否则所有线程公用一个栈的话,会引起调用栈的混乱。
线程和进程也是一样的, 可能会存在僵尸线程,占用了资源不释放,导致资源浪费,所以这里也存在线程等待。新创建的线程都是joinable状态,当线程退出之后需要对其执行pthread_join操作否则无法释放资源造成资源泄漏。还有一个线程属性叫做线程分离属性detach属性,这个属性是需要我们来设置的,它是用来告诉操作系统这个线程我不在乎返回值,如果这个线程退出了你直接把他释放掉就可以了。Joinable和detach属性是相互冲突的两个不能同时存在。