Linux之线程概念

目录

一、细粒度划分

1、堆区细粒度划分

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

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

二、线程的概念

1、基本概念

2、线程的优点

3、线程的缺点

4、线程异常 

5、线程用途

三、Linux下的进程和线程


一、细粒度划分

1、堆区细粒度划分

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

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

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

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

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[ ] 数组中,数组的下标就是该页框的编号。 

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

我们结合下图进行说明。

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

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

二、线程的概念

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、线程的优点

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

3、线程的缺点

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

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;
}

​​​​​​​ 

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、调度优先级

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/436617.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

php安装kafka

我的开发环境是php7.3 ,先来部署两个php扩展&#xff0c;php7.3目录下放librdkafka.dll,ext/php_rdkafka.dll&#xff0c;php.ini增加,[rdkafka] extension php_rdkafka.dll php7.3对应的扩展包链接&#xff1a;PECL :: Package :: rdkafka 看自己php版本对应在这里找PECL :: …

antd vue 选择控件的使用

Ant Design Vue-------Select 选择器 今天就讲讲Ant Design Vue下的控件----select 下拉框 结合项目中的需求&#xff0c;讲一下该控件如何配置&#xff0c;需求&#xff1a; &#xff08;1&#xff09;设置控件的宽度和高度 &#xff08;2&#xff09;绑定数据源 &#x…

IT人才职业发展路径

IT人才的职业发展路径通常是多样化的&#xff0c;因为IT领域涵盖了广泛的技术和职能角色。以下是一个典型的IT人才职业发展路径的梳理&#xff0c;但具体情况会根据个人兴趣、技能、经验和行业需求而有所不同&#xff1a; 入门级岗位&#xff1a; 技术支持工程师&#xff1a;提…

CVE-2024-25600 WordPress Bricks Builder RCE-漏洞分析研究

本次代码审计项目为PHP语言&#xff0c;我将继续以漏洞挖掘者的视角来分析漏洞的产生&#xff0c;调用与利用..... 前方高能&#xff0c;小伙伴们要真正仔细看咯..... 漏洞简介 CVE-2024-25600 是一个严重的&#xff08;CVSS 评分 9.8&#xff09;远程代码执行 (RCE) 漏洞&am…

SpringBoot初步学习

SpringBoot 今日目标&#xff1a; 掌握基于SpringBoot框架的程序开发步骤 熟练使用SpringBoot配置信息修改服务器配置 基于SpringBoot的完成SSM整合项目开发 1. SpringBoot简介 SpringBoot 其设计目的是用来简化 Spring 应用的初始搭建以及开发过程。 1.1 SpringBoot快速…

ROS从入门到精通4-2:Docker安装ROS、可视化仿真与终端复用

目录 0 专栏介绍1 Docker安装ROS2 Docker可视化仿真2.1 显示配置2.2 启动容器 3 终端复用工具3.1 session操作3.2 window操作3.3 pane操作3.4 其他操作 0 专栏介绍 本专栏旨在通过对ROS的系统学习&#xff0c;掌握ROS底层基本分布式原理&#xff0c;并具有机器人建模和应用ROS…

大数据开发-Hadoop之YARN介绍以及实战

文章目录 YARN基本介绍YARN的结构分析YARN中的调度器实际案例&#xff1a;YARN多资源队列的配置和使用 YARN基本介绍 实现Hadoop集群的资源共享不仅支持MapReduce&#xff0c;还支持Spark&#xff0c;Flink等计算 YARN的结构分析 主要复制集群资源的管理和调度&#xff0c;支…

【论文阅读】单词级文本攻击TAAD2.2

TAAD2.2论文概览 0.前言1-101.Bridge the Gap Between CV and NLP! A Gradient-based Textual Adversarial Attack Frameworka. 背景b. 方法c. 结果d. 论文及代码 2.TextHacker: Learning based Hybrid Local Search Algorithm for Text Hard-label Adversarial Attacka. 背景b…

javaWebssh水利综合信息管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh水利综合信息管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCA…

BJFU|操作系统考试复习纲要(思维导图版)

纲要涵盖五个章节&#xff0c;每节一图。红色框部分为必考重点&#xff0c;建议认真复习。

数据结构与算法-归并排序

引言 在计算机科学的广阔领域中&#xff0c;数据结构与算法犹如两大基石&#xff0c;支撑着软件系统高效运行。本文将深度剖析一种基于分治策略的排序算法——归并排序&#xff0c;并探讨其原理、实现步骤以及优缺点&#xff0c;以期帮助读者深入理解这一高效的排序方法。 一、…

用开发CesiumJS模拟飞机飞行应用(一,基本功能)

本部分向您展示如何构建您的第一个 Cesium 应用程序&#xff0c;以可视化模拟从旧金山到哥本哈根的真实航班&#xff0c;并使用 FlightRadar24收集的雷达数据。您将学习如何&#xff1a; 在网络上设置并部署您的 Cesium 应用程序。 添加全球 3D 建筑物、地形和图像的基础图层。…

MySQL 学习笔记(基础篇 Day2)

「写在前面」 本文为黑马程序员 MySQL 教程的学习笔记。本着自己学习、分享他人的态度&#xff0c;分享学习笔记&#xff0c;希望能对大家有所帮助。推荐先按顺序阅读往期内容&#xff1a; 1. MySQL 学习笔记&#xff08;基础篇 Day1&#xff09; 目录 3 函数 3.1 字符串函数 3…

PostgreSQL开发与实战(6.2)体系结构2

作者&#xff1a;太阳 二、逻辑架构 graph TD A[database] -->B(schema) B -->C[表] B -->D[视图] B -->E[触发器] C -->F[索引] tablespace 三、内存结构 Postgres内存结构主要分为 共享内存 与 本地内存 两部分。共享内存为所有的 background process提供内…

VI-ORBSLAM2编译运行

ORB-SLAM2编译运行 源码地址电脑配置环境配置编译轨迹保存为tum格式运行结果Euroc数据集 源码地址 源码链接&#xff1a;https://github.com/jingpang/LearnVIORB 电脑配置 Ubuntu 18.04 ROS Melodic GTSAM 4.0.2 CERES 1.14.0 pcl1.8vtk8.2.0opencv3.2.0 环境配置 之前…

简易版手淘视频播放器开发心路历程

需求背景 简单描述一下这个功能&#xff1a;在一个走马灯组件里面第一屏是一个视频&#xff0c;第二屏第三屏是图片&#xff0c;点击播放视频&#xff0c;播放过程中滚动窗口&#xff0c;视频 fixed 在窗口顶部&#xff0c;回到顶部&#xff0c;视频还原&#xff0c;两个窗口视…

Aigtek:功率放大器的选型技巧有哪些

功率放大器在电子设备中扮演着重要的角色&#xff0c;它能够将输入信号放大到所需要的功率水平。在选择功率放大器时&#xff0c;我们需要考虑多个因素&#xff0c;包括功率需求、频率响应、失真和稳定性等。本文将介绍功率放大器选型的一些技巧&#xff0c;帮助您找到适合的功…

基于OpenCV的图形分析辨认05(补充)

目录 一、前言 二、实验内容 三、实验过程 一、前言 编程语言&#xff1a;Python&#xff0c;编程软件&#xff1a;vscode或pycharm&#xff0c;必备的第三方库&#xff1a;OpenCV&#xff0c;numpy&#xff0c;matplotlib&#xff0c;os等等。 关于OpenCV&#xff0c;num…

java基础-锁之volatilesynchronized

文章目录 volatilevolatile内存语义volatile的可见性volatile无法保证原子性volatile禁止重排优化硬件层的内存屏障volatile内存语义的实现下面是基于保守策略的JMM内存屏障插入策略。下面是保守策略下&#xff0c;volatile写插入内存屏障后生成的指令序列示意图下图是在保守策…

数据结构——lesson6二叉树基础

前言 hellohello~这里是土土数据结构学习笔记&#x1f973;&#x1f973; &#x1f4a5;个人主页&#xff1a;大耳朵土土垚的博客 &#x1f4a5; 所属专栏&#xff1a;数据结构学习笔记 &#x1f4a5;对于数据结构顺序表链表有疑问的都可以在上面数据结构的专栏进行学习哦~感…