进程
- 进程是对运行时程序的封装,是对系统进行资源调度和分配的基本单位;实现操作系统的并发
线程
- 线程是进程的子任务,是CPU调度的和分派的基本单位,用于保证程序的实时性;实现进程内部的并发;
线程是操作系统可识别的最小执行和调度单位。每个线程都独自占用一个虚拟处理器:
独自的寄存器组, 指令计数器和处理器状态。 每个线程完成不同的任务, 但是共享同一地址空间
(也就是同样的动态内存, 映射文件, 目标代码等等) , 打开的文件队列和其他内核资源。
线程与进程对比
(1)概念:
进程是资源分配的最小单位, 线程是 CPU 调度的最小单位;
(2)从属关系
一个线程只能属于一个进程, 而一个进程可以有多个线程, 但至少有一个线程。 线程依赖
于进程而存在
(3)资源
进程在执行过程中拥有独立的内存单元, 而多个线程共享进程的内存。(资源分配给进程,
同一进程的所有线程共享该进程的所有资源。 同一进程中的多个线程共享代码段(代码和常量) ,
数据段(全局变量和静态变量) , 扩展段(堆存储) 但是每个线程拥有自己的栈段, 栈段又叫
运行时段, 用来存放所有局部变量和临时变量。 )
注意:Linux中以“未分配资源的进程描述线程”: 实际上,从内核的角度来看,Linux并没有线程的概念;是否共享地址空间几乎是进程与线程之间的本质的唯一区别。
(4)系统开销
由于在创建或撤消进程时, 系统都要为之分配或回收资源, 如内存空间、 I/o 设备等。 因此, 操作系统所付出的开销将显著地大于在创建或撤消线程时的开销。
类似地,在进行进程切换时,涉及到整个当前进程 CPU 环境的保存以及新被调度运行的进程的 CPU 环境的
设置。
而线程切换只须保存和设置少量寄存器的内容, 并不涉及存储器管理方面的操作。 可见,
进程切换的开销也远大于线程切换的开销。
(5)通信
由于同一进程中的多个线程具有相同的地址空间, 致使它们之间的同步和通信的实
现, 也变得比较容易。 进程间通信 IPC, 线程间可以直接读写进程数据段(如全局变量) 来进行
通信——需要进程同步和互斥手段的辅助, 以保证数据的一致性。 在有的系统中, 线程的切换、同步和通信都无须操作系统内核的干预
(6)编程调试
进程编程调试简单可靠性高, 但是创建销毁开销大; 线程正相反, 开销小, 切换速度快,
但是编程调试相对复杂。
(7)安全性
进程拥有独立地址空间,而线程共享地址空间
所以进程间不会相互影响 ; 线程一个线程挂掉将导致整个进程挂掉
所以多进程的程序要比多线程的程序健壮
(下面这张表应该更加醒目:)
多进程&多线程
各自适用场景
- 多进程
适用于多核,多机分布
(多进程模型, 适用于 CPU 密集型。 同时, 多进程模型也适用于多机分布式场景中, 易于多机
扩展) - 多线程
线程适用于多核分布
多线程程序作为一种多任务、 并发的工作方式, 还有如下优点:
1、 使多 CPU 系统更加有效。 操作系统会保证当线程数不大于 CPU 数目时, 不同的线程运行
于不同的 CPU 上。
2、 改善程序结构。 一个既长又复杂的进程可以考虑分为多个线程, 成为几个独立或半独立
的运行部分, 这样的程序才会利于理解和修改。
有了进程为什么还要有线程(从优缺点,进程线程对比上谈)
线程产生的原因:进程可以使多个程序能并发执行, 以提高资源的利用率和系统的吞吐量; 但是其具有一些缺
点:
(1) 进程缺点:
1> 进程在同一时间只能干一件事
进程在执行的过程中如果阻塞, 整个进程就会挂起, 即使进程中有些工作不依赖于等待的资
源, 仍然不会执行、
2> 对于某些要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程
因此, 操作系统引入了比进程粒度更小的线程, 作为并发执行的基本单位, 从而减少程序在
并发执行时所付出的时空开销, 提高并发性。 和进程相比, 线程的优势如下:
(2)线程优点
1> 从资源上来讲, 线程是一种非常"节俭"的多任务操作方式。
在 linux 系统下, 启动一个新的进程必须分配给它独立的地址空间, 建立众多的数据表来维护它的代码段、 堆栈段和数据段, 这是一种"昂贵"的多任务工作方式。
从切换效率上来讲, 运行于一个进程中的多个线程, 它们之间使用相同的地址空间, 而且线
程间彼此切换所需时间也远远小于进程间切换所需要的时间。 据统计, 一个进程的开销大约是一
个线程开销的 30 倍左右。
2> 从通信机制上来讲, 线程间方便的通信机制。
对不同进程来说, 它们具有独立的数据空间,要进行数据的传递只能通过进程间通信的方式进行, 这种方式不仅费时, 而且很不方便。 线程则
不然,由于同一进城下的线程之间贡献数据空间,所以一个线程的数据可以直接为其他线程所用,
这不仅快捷, 而且方便。
下图可能会更清晰: