1.什么是进程?
当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。
进程由两部分构成:进程内核对象,地址空间。
每个进程至少由三要素组成:程序块、数据块、进程控制块
进程是系统进行资源分配的一个基本单位,是资源分配的最小单位。
进程只能通过通信共享
而一个进程又是由多个线程所组成的。
进程的执行
进程执行的时候通过进程控制块找到入口进入执行,然后将要执行的线程进行压栈及出栈
2.什么是线程?
线程是系统调度的基本单位。
线程是程序中的一个执行流,每个线程都有自己的堆栈、局部变量和专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。
线程也由两部分组成:线程内核对象,操作系统用它来对线程实施管理。线程堆栈,用于维护线程在执行代码时需要的所有函数参数和局部变量。
是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位,是程序执行的最小单位.
线程是一种操作系统对象,代表着一个进程中要被执行的代码的路径。
每个线程启动会默认分配1mb的内存空间,随着具体线程运行内容,会随之更改。
一个线程至少一个栈帧
线程共享解析(纠正网上部分理解)
我们在main方法中创建一个int变量为first,并创建两个线程
此时相当于在主方法栈中创建两个线程栈,如果把first传入这两个线程栈中的话,其实是给他们传了一个副本过去(static同样是如此),此时两个线程栈中处理的first是不同的副本,所以各线程之间不会相互干扰。
而如果是传给普通方法first,就是传了个副本过去,各个栈帧分别处理自己的first,且最后不会同步。
那么共享又是什么意思呢?
意味着线程栈中对first属性进行操作后,会把操作后的结果同步到主方法栈中。
3.二者之间的关系
(1)一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.不同进程之间互不干扰,但是也可以对其他进程进行操作,只是这种操作往往也是借助于操作系统实现。
(2)没有线程的进程可以看做是单线程的,如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。
(3)相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
4.二者之间的区别
1.操作系统资源管理方式不同。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响。线程崩溃时,并不会造成整个进程崩溃,也不一定会影响到其他线程,除非恶性改变了线程之间共享的一些数据。
2.通信机制不同(独立性)。正因为进程之间互不干扰,相互独立,进程的通信机制相对很复杂,譬如管道,信号,消息队列,共享内存,套接字等通信机制,而属于同一个进程的所有线程共享该进程的所有资源,通信机制很方便。。
3.包含关系。线程必定也只能属于一个进程,而进程可以拥有多个线程而且至少拥有一个线程;这一点可以参照上文的第二小节。
4.程序结构不同。举一个简明易懂的列子:当我们使用进程的时候,我们不自主的使用if else嵌套来判断pid,使得程序结构繁琐,但是当我们使用线程的时候,基本上可以甩掉它,当然程序内部执行功能单元需要使用的时候还是要使用,所以线程对程序结构的改善有很大帮助。
5.执行过程不同。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
6.进程是不活泼的。进程从来不执行任何东西,它只是线程的容器。线程总是在某个进程环境中创建的,而且它的整个寿命期都在该进程中。
7.进程使用的系统资源比线程多得多。实际上,线程只有一个内核对象和一个堆栈,保留的记录很少,因此需要很少的内存。进程切换时,耗费资源较大,效率要差一些。因此始终都应该设法用增加线程来解决编程问题,避免创建新的进程。但是许多程序设计用多个进程来实现会更好些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程(单核的情况)。
8.进程是程序的一次动态执行过程,它对应了从代码加载、执行到执行完毕的一个完整过程,这个过程也是进程本身从产生、发展到消亡的过程。线程是比进程更小的执行单位。一个进程在其执行过程能够中,可以产生 多个线程,形成多条执行线索。每条线索,即每个线程也有它自身的产生、存在和消亡过程,也是一个动态的概念。
5.如何选择?
进程与线程的选择取决以下几点:
1、需要频繁创建销毁的优先使用线程,因为对进程来说创建和销毁一个进程代价是很大的。
2、线程的切换速度快,所以在需要大量计算,切换频繁时用线程,还有耗时的操作使用线程可提高应用程序的响应
3、因为对CPU系统的效率使用上线程更占优,所以多机分布用进程,多核分布用线程;
4、并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求;
5、需要更稳定安全时,适合选择进程;需要速度时,选择线程。
6、在进程中进行费时的工作不会导致系统的挂起,但这会导致进程本身的挂起。所以,如果进程既要进行长期的工作,又要响应用户的输入,那么它可以启动一个线程来专门负责费时的工作,而主线程仍然可以与用户进行交互。
6.创建线程和进程的时间开销
线程执行开销小,速度快,但不利于资源的管理和保护;
进程执行开销大,稳定安全,利于资源的管理和保护。
在 Windows 中,进程创建的开销不容忽视。所以Windows 编程中并不建议创建进程,如果你的程序架构需要大量创建进程,那么最好是切换到 Linux 系统。
再次补充:如果你是写服务器端应用的,其实在现在的网络服务模型下,创建线程的开销是可以忽略不计的,因为现在一般流行的是按照 CPU 核心数量开进程或者线程,开完之后在数量上一直保持,进程与线程内部使用协程或者异步通信来处理多个并发连接,因而开进程与开线程的开销可以忽略了。
淘宝双十一为什么有时候会加载不出来?
因为每个人的请求,服务器都分配线程处理,但是线程占空间,人数足够多的时候,便没有足够多的线程可以分配,所以请求被阻塞,每个请求又存储只有1kb,阻塞多个请求并不会占用过多的空间。当前面有线程处理完毕后,再分配线程给请求。