首页 > 系统相关 >Linux——线程(线程概念)

Linux——线程(线程概念)

时间:2024-05-30 22:28:52浏览次数:14  
标签:空间 概念 线程 页表 Linux 进程 PCB os

目录

一、细粒度划分

1.1、堆区细粒度划分

1.2、物理内存和可执行程序细粒度划分

1.3、虚拟地址到物理地址的转化

二、线程概念

2.1、基本概念

2.2、线程优点

2.3、线程的缺点

2.4、线程异常 

2.5、线程用途

三、Linux下的进程和线程


一、细粒度划分

1.1、堆区细粒度划分

        在语言中,我们知道,用户自己申请的空间是存在于地址空间的堆区上的。可是,堆区是一整块空间,我们每次申请只是申请了其中的一小块,并且我们只是说明了申请空间的大小,拿到的是空间的起始地址。如果,我们多次申请了空间,那么我们怎么知道第一次申请的空间是从堆区哪里到哪里呢,第二次申请的空间是从堆区哪里到哪里呢?

        于是os就必须对堆区进行更加精细的管理。在Linux下,每次从堆区申请一块空间,os就会创建结构体 struct vm_area_struct ,该结构体中的数据就是用户申请的每一块空间的相关属性,其中就有空间的起始位置和结束位置。os对于用户申请的空间的管理就成了对结构体链表的管理。os通过这样的精细划分,能够更好地管理用户申请的每一块空间。

        当然,链表的整个范围也一定是在堆区的范围之间的。

上图就是os对堆区的细粒度划分的大概内容。

1.2、物理内存和可执行程序细粒度划分

根据下图,我们来说明。

        首先,我们需要知道:1、a.exe这个可执行程序是一个文件。2、a.exe等可执行程序在磁盘上已经按地址空间的方式编译好了。3、并且a.exe等可执行程序已经被分成了若干个4KB大小的小块,我们称之为页帧。

        当a.exe刚开始运行,一个进程刚开始运行的时候,os首先创建进程的PCB,地址空间,页表,但是还没有通过页表建立虚拟地址到物理地址的联系,而是通过某种硬件方式直接让地址空间找到磁盘上的可执行程序。

        在页表中有一列的数据表示是否在内存中(下图,页表绿色的部分)。当执行具体的代码时,进程必定会通过页表访问物理内存。检测页表时,发现数据不在内存中,于是地址空间不再直接与磁盘上的可执行程序建立联系,os将a.exe加载到物理内存中,通过页表与地址空间建立联系。这叫做缺页中断。

        其实,物理内存也被分成了若干个4KB大小的小空间,我们称之为页框。os将a.exe加载到物理内存中的具体过程就是通过IO,将4KB大小的页帧放进4KB大小的页框中。

        当然,对于这些若干个页框,os也必须对其进行管理。每一个页框都有一个struct page结构体,里面都是页框的各种属性,该结构体中有一个成员flag,表示该页框是否被占用。然后将这些结构体存储到一个 struct page men[ ] 数组中,数组的下标就是该页框的编号。

1.3、虚拟地址到物理地址的转化

        我们早就知道虚拟地址和物理地址之间的联系是通过页表建立的。但是,真正的转化是不止通过一个页表来实现的。

        我们平时所说的地址就是虚拟地址,它一共有32个比特位,页表是一种key,value结构的数据结构。我们通过前10个比特位找到一级页表中的key,然后通过value值找到二级页表,然后通过虚拟地址的第二组10个比特位,找到二级页表的key值位置,接着根据value值找到物理内存中某个页的起始地址。最后,根据虚拟地址的最后12个比特位,进行数值计算,最后找到数据在该页的准确位置。

二、线程概念

2.1、基本概念

        1、在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是一个进程内部的控制序列,一切进程至少都有一个执行线程。

        2、线程在进程内部运行,本质是在进程地址空间内运行。

        3、透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。

        每个进程都有自己独立的地址空间和独立的页表,也就意味着所有进程在运行时本身就具有独立性那么如果我们在创建“进程”时,只创建PCB,并要求新创建出来的PCB与第一次创建的PCB共享地址空间,页表等资源,那么就是下图的情况:

        每个线程都是当前进程里的一个执行流,线程在进程内部运行,准确来说线程在进程的地址空间内运行,拥有并使用该进程的一部分资源。 

        所以说,进程从内核的角度来说就是承担分配系统资源的基本实体,因为线程都是直接从进程处拿到各种资源的。当然,这与我们之前所理解的进程的概念并不矛盾,我们之前的进程都只有一个PCB,也就是该进程内部只有一个执行流,即单执行流进程。从今天开始,我们就会讲到一个进程有多个执行流,即多执行流进程。

        从用户的角度来说,进程就是包括一个或多个PCB(执行流)、地址空间、页表等内核数据结构以及内存中的代码和数据。

线程是CPU调度的基本单位。

        前面,我们说,CPU去处理一个进程的时候,最先拿到的是它的PCB,来决定调度谁。那么,现在我们知道了,准确来说,CPU拿到的是一个线程,因为CPU以task_struct为单位进行调度。

        我们给CPU的task_struct是小于等于过去所说的task_strcut的,比之前的更轻量化了(Linux下的进程也叫做轻量级进程)。因为每一个task_struct只管理着一个进程的一部分资源。它是进程下的一个执行流。

Linux下的线程是用进程PCB模拟的。

        在Linux下,设计者并没有单独为线程设计一个像进程的PCB那样的数据结构, 因为,线程所需要的属性和进程非常相似,所以我们直接复用PCB,用PCB来表示Linux内部的“线程”。但是,如果os真的要专门设计“线程”概念,os那就需要管理线程了:先描述在组织,这样就提高了os的维护成本。

        Linux内核中有没有真正意义的线程,Linux是用进程PCB来模拟线程的,这种设计方法是Linux特有的。

2.2、线程优点

1、创建一个新线程的代价要比创建一个新进程小得多。
2、与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多。
3、线程占用的资源要比进程少很多。
4、能充分利用多处理器的可并行数量。
5、在等待慢速I/O操作结束的同时,程序可执行其他的计算任务。
6、计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现。
7、I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。

2.3、线程的缺点

1、性能损失
        一个很少被外部事件阻塞的计算密集型线程往往无法与共它线程共享同一个处理器。如果计算密集型线程的数量比可用的处理器多,那么可能会有较大的性能损失,这里的性能损失指的是增加了额外的同步和调度开销,而可用的资源不变。
2、健壮性降低
        编写多线程需要更全面更深入的考虑,在一个多线程程序里,因时间分配上的细微偏差或者因共享了不该共享的变量而造成不良影响的可能性是很大的,换句话说线程之间是缺乏保护的。
3、缺乏访问控制
        进程是访问控制的基本粒度,在一个线程中调用某些OS函数会对整个进程造成影响。
4、编程难度提高
        编写与调试一个多线程程序比单线程程序困难得多。

2.4、线程异常 

        单个线程如果出现除零,野指针问题导致线程崩溃,进程也会随着崩溃。线程是进程的执行分支,线程出异常,就类似进程出异常,进而触发信号机制,终止进程,进程终止,该进程内的所有线程也就随即退出 。

#include <iostream>
#include <unistd.h>
#include <string>
#include <pthread.h>
 
using namespace std;
 
void *thread_run(void *argc)
{
    while(true)
    {
        sleep(1);
        int a = 10;
        a /= 0;
    }
}
 
int main()
{
    pthread_t tid;
    pthread_create(tid, nullptr, thread_run, (void *)"thread1");
 
    while (true)
    {
        cout << "main thread pid: " << getpid() << endl;
        sleep(3);
    }
 
    return 0;
}

2.5、线程用途

        合理的使用多线程,能提高CPU密集型程序的执行效率合理的使用多线程,能提高IO密集型程序的用户体验(如生活中我们一边写代码一边下载开发工具,就是多线程运行的一种表现)。

三、Linux下的进程和线程

1、进程是资源分配的基本单位。
2、线程是调度的基本单位。
3、线程共享进程数据,但也拥有自己的一部分数据。

线程共享的进程资源:

1、文件描述符表
2、每种信号的处理方式(SIG_ IGN、SIG_ DFL或者自定义的信号处理函数)
3、当前工作目录
4、用户id和组id

线程需要自己私有的资源:

1、线程ID
2、一组寄存器(线程必须要有自己的上下文)
3、栈(独立的栈结构,能够保存自己的临时变量)

4、errno
5、信号屏蔽字
6、调度优先级

标签:空间,概念,线程,页表,Linux,进程,PCB,os
From: https://blog.csdn.net/m0_69323023/article/details/139265958

相关文章

  • Linux中目录及其操作命令和帮助命令
    目录目录介绍根目录目录操作命令显示目录下的文件和目录的命令用法:常用选项ls-als-all显示当前目录的命令用法切换当前目录的命令用法创建目录的命令用法常用选项删除目录的命令用法注意改变权限的命令用法改变文件或目录的所有者或者组用法常用选项......
  • Linux文件目录指令
    1.pwd   【显示当前工作目录的绝对路径】 2.ls  【-a :显示当前目录所有的文件和目录,包括隐藏的】  【-l :以列表的方式显示信息】 3.cd  【cd~ 或者 cd :回到自己的家目录。如果你是root,就回到/root;如果你是tom,就回到/home/tom】......
  • Linux C进阶 —— 与C++互相调用
      本文介绍C、C++函数互相引用的方法,以及各类目标文件(含.o目标文件、.a静态库、.so动态库)在互调使用中的详细编译链接方法。本文使用arm的交叉编译工具链作为编译和链接工具。1.C调用C++方法(asio为c++库)示例源码树:$tree..├──include│├──asio││├──......
  • 【c++基础(四)】类和对象下--初始化列表等概念
    1.前言类和对象到这里基本已经接近尾声,本篇文章主要介绍一些与类和对象有关的相关细节,在后续使用类和对象中也有可能用的到。本章重点:本篇文章重点讲解初始化列表,友元,匿名对象和类中的static成员,以及类中的内部类的概念。 2.初始化列表 在谈论初始化列表之前就要再次......
  • 【软件测试】软件测试概念 | 测试用例 | BUG | 开发模型 | 测试模型 | 生命周期
    文章目录一、什么是软件测试1.什么是软件测试2.软件测试和调试的区别测试人员需要的素养二、软件测试概念1.需求1.需求的定义2.测试人员眼中的需求2.测试用例1.测试用例概念3.BUG软件错误4、开发模型和测试模型1.软件的生命周期2.开发模型1.瀑布模型2.螺旋模型3.......
  • 【linux】开机调用python脚本
    linux中,可以使用crontab设置开机自动调用crontab的安装在前面文章里写过了,不再重复首先,还是进入crontab配置文件crontab-e进入之后,跟其他定时任务不同,只需要在时间配置那里用@rebooot这类之后的两个文件的配置分别是python的执行文件和需要调用的python脚本位置,还是......
  • linux 定时执行shell、python脚本
    在linux里设置定时执行一般是用crontab,如果没有的话,可以先安装:安装查看是否安装cron-v#对于基于Debian的系统(如Ubuntu)sudoapt-getinstallcron#对于基于RedHat的系统(如CentOS)sudoyuminstallcronie启动cron服务:#对于基于Systemd的系统sudosystemctlstart......
  • SpringBoot直连SAP,IJ IDEA开发与Windows,linux部署
    一、sapjco引入1.1、sapjco介绍sapjco3.jar,连接SAP所需的jar包,linux与windows系统通用libsapjco3.so,linux系统下连接sap所需的动态链接库sapjeco3.dll,windows系统下连接sap所需的动态链接库我使用的版本为sapjco3.0.10<dependency><groupId>com.sap</groupId> <artif......
  • HTML20_web概念1
    一、web概念概述1、JavaWeb:使用Java语音开发基于互联网的项目2、软件架构:1.C/S:Client/Server客户端/服务器端 *在用户本地有一个客户端程序,在远程有一个服务器端程序 *如:QQ,迅雷... *优点: 1.用户体验好 *......
  • C#管理异步线程
    管理异步线程usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Threading;usingSystem.Threading.Tasks;namespacePortClient{///<summary>///异步线程///*修改为枚举类型更合理///</summary>publicstati......