进程和线程有什么区别?
这里我们可以先确定两个大的不同。
- 进程:资源的管理(管理内存,管理打开文件…)
- 线程:调度和执行(调度规则:和进程类似也是抢占式调度)
举个栗子?
比如说小明是一个电子设备加工厂的老板,小明已经开了一间工厂了,可是今年生意好,小明赚了点钱,小明就在想怎么办可以让他赚的更多。
- 那么这个时候如果小明再开一间工厂,这样就可以使生产力翻倍,可是再开一间工厂成本比较大。这就对应的是创建进程,虽然确实可以提高效率,可是创建进程需要再分配一个虚拟地址空间,这样就会使成本增加。
- 那么如果小明在原来的工厂再增加一条生产线,同样可以使生产力翻倍,反而成本降低了。这就对应了创建线程,只需要复制一本主线程的
PCB
稍加修改就可以了。大大降低了成本。
那么通过这个例子,我们可以很清楚的理解进程和线程之间的大体区别。线程就是生产线,进程就是工厂。一个工厂里至少有一个成产线。
线程的概念
- 在一个程序里的一个执行路线就叫做线程。
- 一个进程至少有一个线程。
- 线程在进程内部运行,本质在进程的地址空间内运行。
- 透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。
线程的优点
- 创建或销毁一个线程的代价要比创建或销毁一个进程的代价小得多。
- 与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多。
- 线程占用的资源要比进程少的多。
- 能充分利用多处理器的可并行数量。
- 在等待慢速I/O操作结束的同时,程序可执行其他的计算任务。
- 计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现。
- I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。
CPU(计算)密集型:计算的操作比较多。
I/O密集型:
a) 通过网络进行输入输出。
b) 响应UI界面。(界面显示和数据计算要多线程完成,防止由于数据计算太久导致界面卡死)
线程的缺点
-
性能损失
一个计算机密集型线程,可能没办法和其他计算密集型线程共享这个一个CPU。那么如果计算密集型的线程过多而大于CPU的数量时,就会有性能的损耗。
比如一个桌子上有一块蛋糕,这个桌子只有 8 个位子,一个计算密集型线程占一个位子,如果计算密集型线程太多了,就会使有的线程没办法吃到蛋糕或者吃到很少的蛋糕。
线程多了,不但效率上不去,反而很多时间浪费在了线程间切换上了。因为调度开销大了,效率就会受到影响。
到底需要多少个线程?线程数目和工作任务有关,究竟需要多少个,需要测试的方法来判定。核心在于让 CPU 尽量吃满,让 I/O 尽量吃满。
-
健壮性降低
一个线程异常终止,就会导致整个进程异常终止。(线程异常)
-
缺乏访问控制
线程之间是共享进程的资源的。(线程之间有些资源共用,有些不共用)
就是当一个线程正在修改一个变量的时候,有可能别的线程也同时在修改,进而造成修改错误。
-
编写难度提高
因为线程会使健壮性降低,而且线程是抢占式调度,有的时候某些错误是线程之间必须按某种顺序调度才会出错,所以错误的重现成本也比较大。所以在编写多线程程序时,编写难度会比较大。
线程的用途
- 合理的使用多线程,能提高CPU密集型的程序执行效率。
- 合理的使用多线程,能提高I/O密集型的程序的用户体验。
线程资源的共用与不共用
线程之间共享的资源
- 虚拟地址空间(栈除外)
- 文件描述符表
- 每种信号的处理方式
- 当前工作目录
- 用户id和组id
线程之间不共用的资源
- 栈(函数调用栈、局部变量栈)
main函数对应的线程叫主线程,虚拟的地址空间的栈是主线程的栈。栈和堆之间有一个共享内存区,里面包含线程相间的信息并且每个线程信息内包含自己的栈空间。 - 上下文(CPU中的寄存器信息)
errno
(每个线程由自己的errno
)- 线程ID
- 一组寄存器
- 调度优先级
- 信号屏蔽字
线程和进程之间的区别
- 调度 :进程是操作系统分配资源的一个基本单位。线程是 CPU调度的基本单位。
- 并发性:引入线程之后,不仅进程之间是可以并发执行的,而且在一个进程之中的多个线程也是可以并发执行的,甚至是允许一个进程中的全部线程并发执行。同样,不同的进程中的线程也是可以并发执行的。使得操作系统拥有更好的并发性,提高了资源的利用率和系统吞吐量。
- 拥有资源:进程可以拥有资源,并且是系统拥有资源的基本单位 。线程本身并不拥有系统资源,仅有一些 能保证独立运行 的资源,这块资源的各个线程私有的。例如,线程ID、一组寄存器、栈、
errno
、信号屏蔽字(一个进程中pending信号只有一个,但是任意一个线程都可以处理这个信号)、调度优先级。 - 独立性:在同一进程中线程的独立性要比在不同的进程中独立性要低很多 。
- 系统开销:线程切换的开销低于进程切换的开销。
- 支持多处理机系统:对于传统的进程,也就是单线程进程 ,不管有多少个处理机,进程只能运行在同一个 处理机上面,但对于多线程进程,就可以将一个进程中的多个线程分配到多个处理机上面,使其并发执行,加速了进程的完成。
小结
- 线程不是越多越好,当线程的数量多到一定程度的时候(超过CPU的数量),效率反而并不能提高
- 线程如果多了,多个线程尝试访问同一个资源就会打架(通过互斥来解决)
- 某个线程可能一直得不到执行的机会,这就叫做线程饥饿(通过同步来解决)
- 如果某个线程异常终止,整个进程就都异常终止了
叮~?