进程process:
是计算机中已运行程序的实体。程序本身只是指令、数据及其组织形式的描述,进程才是程序(那些指令和数据)的真正运行实例。
同一程序可产生多个进程(一对多关系),以允许同时有多位用户运行同一 程序,却不会相冲突。
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。
线程thread:
是操作系统能够进行运算调度的最小单位。是独立调度和分派的基本单位。
一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务;一个线程可以创建和撤销另一个线程。
线程可以为操作系统内核调度的内核线程。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈), 但是同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时运行,但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。
一个进程中的所有线程共享该进程的地址空间,但它们有各自独立的(/私有的)栈(stack),win线程的缺省堆栈大小为1M。堆heap的分配与栈有所不同,一般是一个进程有一个C运行时堆,
这个堆为本进程中所有线程共享,win进程还有进程默认堆,用户也可以自己创建堆。用操作系统术语,就是线程切换的时候实际上切换的是一个可以称之为线程控制块的结构(TCB),里面
保存所有将来用于恢复线程环境的必须信息,包括所有必须保存的寄存器集,线程的状态。
堆:是公有的空间,分为全局堆和局部堆。全局堆就是所有没有分配的空间,局部堆就是用户分配的空间。堆在操作系统对进程初始化的时候分配,运行过程中也可以像系统要额外的堆,但是记得
用完了要还给操作系统。要不然就是内存泄漏。
栈:是线程独有的,保存其运行状态和局部自变量。栈在线程开始的时候初始化,每个线程的栈相互独立。因此,栈是Thread safe的。操作系统在切换线程的时候后自动切换栈,即切换
SS<栈段寄存器>/ESP<栈顶指针>寄存器。栈空间不需要再高级语言里面显示的分配和释放。
线程管理:
将线程公有的信息放在进程控制块里,将线程独有的信息存放在线程控制块中。
如何区分哪些信息时共享?哪些私有?
一般的评价标准是:如果某些资源不独享会导致线程运行错误,则该资源就由某个线程独享,而其他资源都由进程里面的所有线程共享。
对于进程一线程的实现如何做解释?
首先应该明白进程的调度,创建等实质上都是有操作系统实现的,即进程的实现只能由操作系统内核来实现,而不存在用户态实现的情况。
对于线程,线程的管理者可以是用户也可以是操作系统本身。因此,线程的实现就应该分为内核态线程实现和用户态线程实现。
内核态线程实现:
线程时进程的不通过执行序列,即线程是独立运行的基本单位,也是CPU的基本单位。
操作系统如何实现线程管理?
首先操作系统向管理进程一样,应该保持维护线程的所有资源,将线程控制块存放在操作系统的内核空间中。那么此时操作系统就同时掌控进程控制块和线程控制块。
优点:用户编程简单;不容易阻塞。缺点:效率低,需要修改操作系统。
用户态线程实现:
用户自己做线程的切换,操作系统无需知道线程的存在。
需要创建一个调度线程,在执行完需主动把资源释放给其他线程使用。 优点:灵活,无需修改操作系统实现。缺点:需要考虑很多原因,
现在操作系统的线程实现模型:
用户态执行负责进程内部线程在非阻塞时的切换;内核态的操作系统负责阻塞线程的切换。每个内核态线程可以服务一个或多个用户态线程。
线程什么时候会从用户态切换到内核态:
首先,如果程序运行过程中发生中断或者异常,系统将自动切换到内核态运行中断或异常处理机制;或者,程序进行系统调度也会从用户态切换到内核态。
原文地址:https://www.cnblogs.com/liamlee/p/9393553.html