进程、线程、协程和管程

这里写目录标题

  • 进程、线程、协程和管程的概念
  • 进程和线程区别
  • 线程和协程的区别
  • 协程为什么叫用户态线程
  • 进程/线程切换所需要保存的信息
  • 同一进程间的线程共享/独享哪些资源
  • 线程崩溃一定会导致进程崩溃吗?
  • 进程和程序的区别
  • 线程的回收

进程、线程、协程和管程的概念

进程是操作系统进行资源分配和调度的一个基本单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。进程上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。

线程是CPU调度和分派的基本单位,一个进程可以拥有多个线程。线程自己基本上不拥有系统资源,只拥有少部分的资源(如程序计数器,一组寄存器和栈)。线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。

协程是一种用户态的轻量级线程,一个线程也可以拥有多个协程。协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程的上下文切换非常快。

管程是一种程序结构,结构内的多个子程序(对象或模块)形成的多个工作线程互斥访问共享资源。在一个时间点,最多只有一个工作线程在执行管程的某个子程序。管程实际上是定义的一种数据结构和控制进程的一些操作的集合

进程和线程区别

  • 根本区别:进程是系统进行资源分配(如地址和文件等)的基本单位;线程是CPU调度和分派的基本单位。

  • 拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源(但线程有自己的堆栈和局部变量),但可以访问隶属于进程的资源。进程所维护的是程序所包含的资源(静态资源), 如:地址空间,打开的文件句柄集,文件系统状态,信号处理handler等;线程所维护的是线程运行相关的资源(动态资源),如:运行栈等

  • 包含关系:一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

  • 切换:上下文切换包含了寄存器的存储和程序计数器存储的指令内容。进程切换与线程切换的一个最主要区别就在于进程切换涉及到虚拟地址空间的切换而线程切换则不会。因为每个进程都有自己的虚拟地址空间,而线程是共享所在进程的虚拟地址空间的,因此同一个进程中的线程进行线程切换时不涉及虚拟地址空间的转换。

线程和协程的区别

  1. 一个线程可以多个协程,协程需要线程来承载运行。从这个角度讲,线程是协程的资源。
  2. 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态。
  3. 线程是由CPU调度,而协程是由用户调度。

协程为什么叫用户态线程

简单来说,线程(thread)的调度是由操作系统负责,线程的睡眠、等待、唤醒的时机是由操作系统控制,开发者无法决定。使用协程,开发者可以自行控制程序切换的时机,可以在一个函数执行到一半的时候中断执行,让出CPU,在需要的时候再回到中断点继续执行。简单来说就是用户可以更加直接的控制协程。

进程/线程切换所需要保存的信息

进程调度:进程主要包括程序段、数据段、PCB三个部分,切换进程上下文主要需要切换分配的内存、代码段、数据段、堆栈段、

线程调度:切换线程上下文,主要切换栈以及各寄存器的值

同一进程间的线程共享/独享哪些资源

共享的资源有:

  • :由于堆是在进程空间中开辟出来的,所以它是理所当然地被共享的;因此new出来的都是共享的(16位平台上分全局堆和局部堆,局部堆是独享的)
  • 全局变量:它是与具体某一函数无关的,所以也与特定线程无关;因此也是共享的
  • 静态变量:虽然对于局部变量来说,它在代码中是“放”在某一函数中的,但是其存放位置和全局变量一样,存于堆中开辟的.bss和.data段,是共享的
  • 文件等公用资源:这个是共享的,使用这些公共资源的线程必须同步。Win32 提供了几种同步资源的方式,包括信号、临界区、事件和互斥体。

注意:每个进程都有自己的地址空间,即进程可以访问的虚拟地址范围。每个进程可以有多个线程,所以进程中的所有线程共享相同的虚拟地址空间

独享的资源有:

  • :栈是独享的,线程默认栈大小为8M。
  • 寄存器的值:这个可能会误解,因为电脑的寄存器是物理的,每个线程去取值难道不一样吗?其实线程里存放的是副本,包括程序计数器PC。

线程崩溃一定会导致进程崩溃吗?

线程崩溃的本质就是内存出错。而内存出错有时不会引起其他线程出错的,因为崩溃的线程,也就是出错的内存有时侯没有被其他线程访问,也就不会产生问题,但有时候会打乱其他线程的内存。

进程和程序的区别

  1. 进程是暂时的,是程序在数据集上的一次执行,程序是永存的。
  2. 进程是动态的观念,程序是静态的观念。
  3. 1个进程一般只能对应1个程序,1个程序可以对应多个进程。

线程的回收

pthread回收线程的方式如下::

  1. 子线程调用 pthread_detach(pthread_self())。
  2. 主线程调用 pthread_join() 一直等待子线程结束。

你可能感兴趣的:(操作系统,操作系统,进程,线程,协程,管程)