1. 什么是进程和线程
现代操作系统比如Mac OS X,UNIX,Linux,Windows等,都是支持“多任务”的操作系统。
1.1 百科解释
进程(Process) 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。 在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。程序是指令、数据及其组织形式的描述,进程是程序的实体。
线程(thread) 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
1.2 简单理解
线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
一个进程由几个线程组成(拥有很多相对独立的执行流的用户程序共享应用程序的大部分数据结构),线程与同属一个进程的其他的线程共享进程所拥有的全部资源。
进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。
线程有自己的堆栈和局部变量,但线程没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
1.3 总结
进程:指在系统中正在运行的一个应用程序;程序一旦运行就是进程;进程——资源分配的最小单位。
线程:系统分配处理器时间资源的基本单元,或者说进程之内独立执行的一个单元执行流。是程序执行的最小单位。
2. 具体理解
在Linux环境下,每个进程有自己各自独立的 4G 地址空间,大家互不干扰对方,如果两个进程之间通信的话,还需要借助第三方进程间通信工具 IPC 才能完成。不同的进程通过页表映射,映射到物理内存上各自独立的存储空间,在操作系统的调度下,分别轮流占用CPU去运行,互不干扰、互不影响,甚至相互都不知道对方。在每个进程的眼里,CPU就是他的整个世界,虽然不停地被睡眠,但是一旦恢复运行,一觉醒来,仿佛什么都没发生过一样,认为自己拥有整个CPU,一直在占有它。
在一个进程中,可能存在多个线程,每个线程类似于合租的每个租客,除了自己的私有空间外,还跟其它线程共享进程的很多资源,如地址空间、全局数据、代码段、打开的文件等等。在线程中,通过各种加锁解锁的同步机制,一样可以用来防止多个线程访问共享资源产生冲突,比如互斥锁、条件变量、读写锁等。
进程具有的特征:
- 动态性:进程是程序的一次执行过程,是临时的,有生命期的,是动态产生,动态消亡的;
- 并发性:任何进程都可以同其他进行一起并发执行;
- 独立性:进程是系统进行资源分配和调度的一个独立单位;
- 结构性:进程由程序,数据和进程控制块三部分组成
对于操作系统来说,它可以同时运行多个任务。你可以一边听歌,一边打游戏,一边还等着QQ开着语音聊着天,这就是多任务,至少同时有3个任务正在运行。还有很多任务悄悄地在后台同时运行着,只是桌面上没有显示而已。对于过去的单核CPU,也可以完成这些任务,由于CPU执行代码都是顺序执行的,那么,单核CPU就轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒……这样反复执行下去。表面上看,每个任务都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像所有任务都在同时执行一样。
真正的并行执行多任务只能在多核CPU上实现,但是,由于任务数量远远多于CPU的核心数量,所以,操作系统也会自动把很多任务轮流调度到每个核心上执行。
对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了一个Word进程。
有些进程还不止同时干一件事,比如Word,它可以同时进行打字、拼写检查、打印等事情。在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)。
由于每个进程至少要干一件事,所以,一个进程至少有一个线程。当然,像Word这种复杂的进程可以有多个线程,多个线程可以同时执行,多线程的执行方式和多进程是一样的,也是由操作系统在多个线程之间快速切换,让每个线程都短暂地交替运行,看起来就像同时执行一样。当然,真正地同时执行多线程需要多核CPU才可能实现。
3. 为什么使用多线程?
① 和进程相比,它是一种非常“节俭”的多任务操作方式。在Linux系统中,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护其代码段、堆栈段和数据段,这种多任务工作方式的代价非常“昂贵”。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且线程间彼此切换所需要时间也远远小于进程间切换所需要的时间。
② 线程间方便的通信机制。对不同进程来说它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行。这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其他线程所用,不仅方便,而且快捷。
4. 进程和线程的区别
第一:什么是进程,什么是线程?
- 进程是程序一次执行的过程,动态的,进程切换时系统开销大
- 线程是轻量级进程,切换效率高
第二:进程和线程的空间分配?
- 进程:每个进程都有独立的0-3G的空间,都参与内核调度,互不影响
- 线程:同一进程中的线程共享相同的地址空间(共享0-3G)
第三:进程之间和线程之间各自的通信方式
- 进程间:(7种)无名管道、有名管道、信号机制、信号灯、共享内存、消息队列、套接字socket
- 线程间:全局变量,信号量,互斥锁