进程和线程的区别
文章目录
- 进程和线程的区别
- 进程和线程的概念
- 一、从属关系不同
- 二、所属基本单位不同
- 三、资源消耗不同
- 四、是否同步和互斥
- 额外补充问题:一个进程是不是可以创建无限数量的线程?
- 参考链接
进程和线程的概念
在了解区别之前,我们先了解什么是进程和线程:
- 进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。
- 线程是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。
以下就开始介绍两者区别
一、从属关系不同
进程是正在运行程序的实例,进程中包含了线程,而线程是轻量级的进程,一个进程中包含了多个线程,因此多个线程间可以共享进程资源,线程和进程的关系如下图所示:
其中,堆和方法区是可以共享的区域,而程序计数器和栈是每个线程私有的。
- 程序计数器是一块内存区域,用来记录线程当前要执行的指令地址。
- 栈是用来记录每个线程自己的局部变量的。
- 堆中存放的是当前程序创建的所有对象。
- 方法区存放的是常量和静态变量等信息。
二、所属基本单位不同
进程是资源分配的最小单位,线程是程序执行的最小单位。
同一个进程可以包含多个线程,一个进程中至少包含一个线程,一个线程只能存在于一个进程中
以下节选自《Unix网络编程》
fork is expensive. Memory is copied from the parent to the child, all
descriptors are duplicated in the child, and so on. Current
implementations use a technique called copy-on-write, which avoids a
copy of the parent’s data space to the child until the child needs its
own copy. But, regardless of this optimization, fork is expensive.IPC is required to pass information between the parent and child after
the fork. Passing information from the parent to the child before the
fork is easy, since the child starts with a copy of the parent’s data
space and with a copy of all the parent’s descriptors. But, returning
information from the child to the parent takes more work.Threads help with both problems. Threads are sometimes called
lightweight processes since a thread is “lighter weight” than a
process. That is, thread creation can be 10–100 times faster than
process creation.All threads within a process share the same global memory. This makes
the sharing of information easy between the threads, but along with
this simplicity comes the problem
三、资源消耗不同
进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。
而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建及销毁一个线程的开销也比进程要小很多。
四、是否同步和互斥
线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC) 进行。并且线程在执行时是同步和互斥的,毕竟他们共享同一个进程下的资源,所以如何处理好同步与互斥是编写多线程程序的难点。
额外补充问题:一个进程是不是可以创建无限数量的线程?
不是。
操作系统给一个系统进程提供的空间是2GB ,而一个线程堆栈的空间默认在启动的时候是1MB,理论上最大线程数=2GB/1MB=2048。但是内存当然不可能完全拿来作线程的栈,所以实际数目要比这个值要小。你也可以通过连接时修改默认栈大小,将其改的比较小,这样就可以多开一些线程。如将默认栈的大小改成512K,这样理论上最多就可以开4096个线程。
如果是同一台机器内的话,能起多少线程也是受内存限制的。
参考链接
链接: 一道面试题:说说进程和线程的区别
链接: 进程与线程的一个简单解释
链接: 进程和线程有什么区别
链接: 线程进程区别