• Linux线程概况


    PCB(progress control block)与进程分配资源

    PCB(progress control block),进程控制块。
    当一个可执行程序被系统执行了以后,就变成了一个进程。

    那么这个进程中到底有什么东西呢?
    系统究竟给这个进程分配了哪些资源?
    另外,进程在内存中的存储是怎么样的?
    对于一个进程,它在被执行前其实是一个可执行程序。这个程序是被放在磁盘上的,当它要被执行的时候,它先被加载到内存当中,然后再放入到寄存器中,最后再让cpu执行该程序,这个时候一个静态的程序就变成了进程。

    那么操作系统是怎么来管理这些进程的呢?
    操作系统通过一个双向链表把进程连起来。
    但是,对于进程其实它是一个抽象的概念,系统肯定要通过一个东西来描述进程,然后才能管理进程。于是PCB就出来了,操作系统通过PCB来描述进程,于是这个双向链表连接的其实是PCB。

    这个PCB是个什么玩意?
    它就是一个结构体,用来描述进程,在Linux下,就是task_struct结构体。

    基本概念

    LWP

    light weight process 轻量级的进程,本质仍是进程(在Linux环境下)

    进程

    独立地址空间,拥有PCB,最小分配资源单位,可看成是只有一个线程的进程。

    线程

    也有PCB,但没有独立的地址空间(共享),Linux下最小的执行单位,调度的基本单位。

    进程和线程区别

    在于是否共享地址空间。
    独居(进程)
    合租(线程)。

    Linux内核线程实现原理

    历史

    类Unix系统中,早期是没有“线程”概念的,80年代才引入,借助进程机制实现出了线程的概念。因此在这类系统中,进程和线程关系密切。

    进程和线程是都有各自不同的PCB

    轻量级进程(light-weight process),也有PCB,创建线程使用的底层函数和进程一样,都是clone。
    从内核里看进程和线程是一样的,都有各自不同的PCB,但是PCB中指向内存资源的三级页表是相同的。

    进程可以蜕变成线程。

    线程可看做寄存器和栈的集合。

    在linux下,线程最是小的执行单位;进程是最小的分配资源单位。

    察看LWP号:ps –Lf pid 查看指定线程的lwp号。

    进程的目录、页表、物理页面各不相同

    对于进程来说,相同的地址(同一个虚拟地址)在不同的进程中,反复使用而不冲突。原因是他们虽虚拟址一样,但,页目录、页表、物理页面各不相同。相同的虚拟址,映射到不同的物理页面内存单元,最终访问不同的物理页面。

    三级映射:进程PCB --> 页目录(可看成数组,首地址位于PCB中) --> 页表 --> 物理页面 --> 内存单元
    –参考:《Linux内核源代码情景分析》 ----毛德操

    线程之间共享同一个页目录

    两个线程具有各自独立的PCB,但共享同一个页目录,也就共享同一个页表和物理页面。所以两个PCB共享一个地址空间。

    创建进程或者创建线程底层都是调用内核函数clone

    实际上,无论是创建进程的fork,还是创建线程的pthread_create,底层实现都是调用同一个内核函数clone。

    Linux内核是不区分进程和线程的

    如果复制对方的地址空间,那么就产出一个“进程”;
    如果共享对方的地址空间,就产生一个“线程”。
    因此Linux内核是不区分进程和线程的。
    只在用户层面上进行区分。所以,线程所有操作函数 pthread_* 是库函数,而非系统调用。

    线程共享资源

    1.文件描述符表
    2.每种信号的处理方式
    3.当前工作目录
    4.用户ID和组ID
    5.内存地址空间 (.text/.data/.bss/heap/共享库)

    线程非共享资源

    1.线程id
    2.处理器现场和栈指针(内核栈)
    3.独立的栈空间(用户空间栈)
    4.errno变量
    5.信号屏蔽字
    6.调度优先级

    线程优、缺点

    优点: 1. 提高程序并发性 2. 开销小 3. 数据通信、共享数据方便
    缺点: 1. 库函数,不稳定 2. 调试、编写困难、gdb不支持 3. 对信号支持不好
    优点相对突出,缺点均不是硬伤。Linux下由于实现方法导致进程、线程差别不是很大

    参考资料

    https://blog.csdn.net/qq_22847457/article/details/89371217
    https://blog.csdn.net/qq_22847457/article/details/90291051
    《Linux内核源代码情景分析》

  • 相关阅读:
    ESP32蓝牙实例-BLE服务器与客户端通信
    用Python制作七夕表白神器,让你成功概率提高99.9%
    实习面试记录
    XILINX XC7A200T-1FBG676C FPGA - 现场可编程门阵列
    Java数组
    fork()函数与僵尸进程
    数据结构-二叉树力扣题
    网络面试-0x05 什么是http(s)以及它们的区别?
    Vuex中多个参数显示undefined的解决方案
    [附源码]java毕业设计览宏公司会议管理系统
  • 原文地址:https://blog.csdn.net/Shujie_L/article/details/134468997