美文网首页
进程与线程

进程与线程

作者: jluemmmm | 来源:发表于2021-11-23 10:19 被阅读0次

    进程

    • 进程是对运行时程序的封装,是系统进行资源调度和分配的基本单位,实现了操作系统的并发

    线程

    • 线程是进程的子任务,是CPU调度和分派的基本单位,用于保证程序的实时性,实现进程内部的并发
    • 线程是操作系统可识别的最小执行和调度单位
    • 每个线程都独自占用一个虚拟处理器,独自的寄存器组,指令计数器和处理器状态

    创建成本

    • 创建进程需要为进程划分出一块完整的内存空间,有大量的初始化操作,比如要把内存分段(堆栈、正文区等)
    • 创建线程则简单得多,只需要确定 programer counter指针和寄存器的值,并且给线程分配一个栈用于执行程序,同一个线程间可以复用堆栈。

    上下文切换

    进程

    当一个进程在执行时,CPU的所有寄存器的值、进程的状态及堆栈中的内容被称为该进程的上下文。当内核需要切换到另一个进程时,它需要保存当前进程的所有状态,即保存当前进程的上下文,以便在再次执行该进程时,能够得到切换时的状态执行下去。在linux中,当前进程上下文均被保存在进程的任务数据结构中。在发生中断时,内核就在被中断进程的上下文中,在内核态下执行中断服务例程。但同时会保留所有需要用到的资源,以便中断服务结束时能恢复被中断进程的执行。

    线程

    线程是调度的基本单位,进程是资源拥有的基本单位。内核中的任务调度,实际上调度的对象是线程,进程是给线程提供虚拟内存、全局变量等资源的。当进程拥有多个线程时,线程共享相同的虚拟内存和全局变量等资源,这些资源在上下文切换时不需要修改。当线程也有自己的私有数据时,比如自己的栈和寄存器,上下文切换时也需要保存。

    线程的上下文切换存在两种情况:

    • 前后切换的两个线程属于同一个进程,两个线程的资源基本是共享的,切换上下文时共享的资源不需要动,只有当线程有私有数据时,切换这些不共享的数据即可。
    • 前后切换的两个线程不属于同一个进程,跟切换进程的上下文是一样的。

    切换同一进程的线程比切换进程消耗更少的系统资源,是多线程对比对进程的优势

    同一个进程的线程中的资源分配

    线程之前独有的资源

    thread context
    • 函数运行时需要额外的寄存器来保存一些信息,像局部变量,这些寄存器是线程私有的,一个线程不可能访问到另一个线程的这类寄存器信息。
    • 所属线程的栈区、程序计数器、栈指针以及函数运行使用的寄存器是线程私有的,这些信息有一个统一的名字,线程上下文,thread context
    TLS -- Thread Local Storage

    存放在该区域中的变量的是全局变量,所有线程都可以访问,但是每个线程在访问的时候都会存储一份成为自己的局部变量,修改就不会相互影响了。看上去所有的线程访问的都是同一个变量,但该全局变量独属于一个线程,一个线程对此变量的修改对其他线程不可见。
    实现原理类似有一个全局的词典,词典的key是线程id,value就是共享的全局变量的副本。

    线程之前共享的资源

    代码区

    编译后的代码

    数据区

    全局变量,静态变量

    堆区

    C/C++中用malloc或者new 出来的数据就存放在这个区域,只要知道指针,任何一个线程都可以访问指针指向的数据,因此堆区也是线程共享的属于进程的资源。

    栈区

    如果一个线程能拿到来自另一个线程栈上的指针,那么该线程就可以改变另一个线程的栈区,也就是说这些线程可以任意修改本属于另一个线程栈区中的变量。

    动态链接库

    动态链接的部分生成的库就是我们熟悉的动态链接库,在windows下是以ddl结尾的文件,在linux下是以so结尾的文件。

    文件

    如果程序在运行过程中打开了一些文件,那么进程地址空间中还保存有打开的文件信息,进程打开的文件也可以被所有的线程使用,这也属于线程间的共享资源

    相关文章

      网友评论

          本文标题:进程与线程

          本文链接:https://www.haomeiwen.com/subject/dygvtrtx.html