Linux:线程

我恨死大物实验、模电实验、嵌入式实验、概率论和满实验室飞的蚊子了!!!

前言:

OS进行内存管理,是以内存块为单位管理的,一个块默认是4kb,一个块里有八个扇区

查看当前系统下的块的大小:

getconf PAGESIZE

系统和磁盘进行IO的基本单位都是4kb,页(虚拟)是系统的最小单位,块是磁盘的最小单位

4kb也可以被称为页框/页帧,OS对内存的管理工作的基本单位也是4kb

拷贝(立即拷贝)的时候也是把所有的页框拷贝过去,尽管并不是所有数据都是立即用到,但是这样可以防止在复制的时候发生缺页中断,但是会占用内存(空间换时间)

struct page
{int flag;     //是否被占用,是否是脏页,是否被锁定int mode;...
}

*脏页:修改文件数据的时候不包含马上同步到磁盘,会缓存在内存的page cache中,这种和磁盘数据不一样的页为脏页

大概就像这样,没有上传更改的时候就是脏页

组织一个页表需要用数组来管理

struct page memory[1048576]

下标就是每个内存页框的地址

MMU(内存管理单元)会将虚拟地址映射成物理地址

页表也是有等级的

一级页表:简单的单层页表,每个虚拟地址直接映射到物理地址

多级页表:每一级都进一步细分为虚拟地址,避免单一页表占据过多空间(就像一级、二级目录一样)

也就是说一级页表会映射多个页(一个一级目录底下有很多各个目录下的详细内容)

一级页表有1024(2的10次方)个条目,也就是说它的前十位用于索引(索引1024个页表,存的是他们的页表起始地址)其余地址部分用于后续级别的页表索引或页内偏移

举个栗子:

一个32位地址+二级页表

一个典型的二级页表是这样划分虚拟地址的:前十位作为高10位,用于索引一级页表(有2的10次方个目录);中十位用于索引二级页表(也有2的10次方个目录);低十二位用于业内偏移(每页大小为2的12次方=4kb=4096bit)

一个地址为0x12345678,前20位(0x12345)指的是第几个页表条目,页表中存放的起始地址,而后12位(0x678)就是页内偏移,来确定在这个页内的具体字节位置

假如这个0x12345678映射的物理页框是0xABC00000,那么物理地址就是0xABC00000+0x678==0xABC00678

在代码中,一块函数里有很多行代码,每行代码都有自己的地址,每行的地址在一个函数内都是连续的;一个函数对应一批连续的虚拟地址,函数是连续地址构成的代码块

线程的概念/Linux下线程的实现

线程俗称是“进程的进程”,是CPU调度的基本单位(进程是资源分配和调度的基本单位)

我们还是讨论task_struct,地址空间,页表,物理内存的关系

偷偷放别人的图

每个进程都有自己独立的地址空间,进程之间切换和通信有比较大的工作量;但是线程在同一个进程内可以共享进程的地址空间,切换的工作量比较小

所以在底层上,我们要执行一个新的task的时候,创建一个新的task_struct的时候,不额外创建地址空间和页表,而是指向我们之前创建的地址空间和页表,正文代码不同的部分交给不同的线程去执行,所以这些线程共享这个进程的地址空间。

这张图是偷贩卖纯净水的,将进程资源分配给每个执行流,形成线程执行流

一切进程里至少有一个执行线程,线程在进程内部执行,本质上是在进程的地址空间内运行

我们之前说到进程=进程内核数据结构+进程的代码和数据

进程是承担分配系统资源的基本实体

之前我们学的进程是内部只有一个执行流的进程

而多线程进程就是内部有多个执行流的进程

如果OS要设计一个线程,那个这个线程是不是要经历新建、暂停、销毁、调度(具有和进程相同的部分)

那既然线程是进程的进程,那么我们的线程肯定也要和进程扯上关系,怎么扯上关系?

进程有进程的控制块(PCB),线程有线程的控制块

在Windows上,真的有提供给线程的线程控制块

而在Linux上,线程是直接复用进程的PCB格式,毕竟他们也都需要新建、暂停、销毁、调度

那么CPU怎么区分task_struct是进程还是线程?

答案是完全没必要区分!因为对于一个CPU来说,他们都是执行流

CPU眼里的进程都叫执行流,都是轻量级进程

线程在进程内部运行,是CPU调度的基本单位,进程是承担分配资源的基本实体

来看看创建线程的接口函数

第一个参数,pthread_t *thread:类似于获取进程pid的getpid()

第二个参数,const pthread_attr_t *attr:定制线程的类型,一般设置为NULL,可用作制作默认属性的线程

第三个参数,void *(*start_routine) (void *):一个函数,线程会执行这个函数,新创建的线程从start_rtn函数的地址开始运行,该函数只有一个无类型指针参数arg

第四个参数,void *arg:执行函数中中参数。如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构体中,然后把这个结构的地址作为arg参数传入

pth.c

#include<stdio.h>
#include<pthread.h>
void* gopthread(void *arg){while(1){sleep(1); printf("this is a pthread,tid==%d\n",getpid());}
}
int main(){pthread_t tid;pthread_create(&tid,NULL,gopthread,(void*)"thread-new");while(1){sleep(1);printf("main going\n");}return 0;
}

可以看见两个执行流在交替执行,但是只有一个进程

怎么查看线程?

ps -aL

上图的LWP是什么呢?

叫轻量级进程(Light Weight Process),也就是线程

OS进行调度的时候是看的LWP,而不是pid,因为LWP是线程

那么LWP和tie什么关系?答案是他们都是线程的id,但是tid在系统提供的接口函数中更常用

上图的pid和lwp的数值有的一样,有的不一样,一样的是主线程

多线程的必要性

我们既然可以创建很多个进程,那么为什么还要有线程的概念

我们之前也提到线程创建的成本比进程的成本低多了,因为线程不需要额外创建页表、地址空间等等,而且删除也很方便

我们明白了创建成本为什么低,为什么说线程的调度成本低?

不同线程的地址空间是共享的,是同一张页表;CPU 在调度进程的时候,不同系统对进程和线程的实现是不一样的,CPU内存有着cache,我们的代码会预先加载到cache里,这叫热数据,cache是CPU中的硬件

你怎么知道的?

lscpu//主要是用来显示CPU结构相关信息

如果是进程间切换调度的时候,cache里的数据都要重新换;带上线程就不需要,因为cache上的数据是可能被用上的

那如果进程里执行的线程就是一个操作系统呢?

那就是虚拟机啊!(一个进程挂掉不会影响另一个进程)

通过进程的虚拟地址空间,可以看到进程的大部分资源,再将资源合理分配给每个执行流,也就是线程;而线程也不是越多越好,合适的才是最好的,双核CPU创建两个线程比较好

线程的优点

创建成本低

切换工作少

占用资源少

能充分利用多处理器的可并行数量

等待慢速I/O操作结束的同时,程序可以执行其他计算任务

计算密集型应用,可以分解到多个线程实现(协程是交替实现)

 I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作

缺点

性能损失:一个密集型应用的线程无法与其他线程共享多个处理器,如果密集型线程的数量比可用的CPU多,那么就会造成较大的性能损失(性能损失:增加了额外的同步和调度开销,但是可用资源不变)

健壮性降低:一个多线程的任务中,如果因为时间上的分配导致的细微偏差或者因共享了不该共享的变量(野指针、除以0等)而造成的不良影响蛮大的,也就是说线程和线程之间是没有保护机制的

缺乏访问控制:进程是访问的基本粒度,在线程里调用进程的OS函数会对整个进程造成影响

编程难度高: 编写与调试一个多线程程序比单线程程序困难得多

我们来写一个代码证明线程健壮性低:

pth.c:

#include<stdio.h>
#include<pthread.h>
void* gopthread(void *arg){while(1){sleep(5); printf("this is a pthread,pid==%d\n",getpid());int x=rand()%5;if(x==0){int *p=NULL;*p=100;//段错误,访问空指针}}
}
int main(){srand(time(NULL));pthread_t tid1;pthread_create(&tid1,NULL,gopthread,(void*)"thread-new");pthread_t tid2;pthread_create(&tid2,NULL,gopthread,(void*)"thread-new");pthread_t tid3;pthread_create(&tid3,NULL,gopthread,(void*)"thread-new");while(1){sleep(5);printf("main going,pid==%d\n",getpid());}return 0;
}

可以看见所有的线程都挂起了(顺便一说,TTY是伪终端)

来看看证明线程的缺乏访问控制:

pth.c:

#include<stdio.h>
#include<pthread.h>
int gval=100;
void* gopthread(void *arg){while(1){sleep(5); printf("this is a pthread,pid==%d\n",getpid());int x=rand()%5;if(x==0){int *p=NULL;*p=100;//段错误,访问空指针}}
}
int main(){srand(time(NULL));pthread_t tid1;pthread_create(&tid1,NULL,gopthread,(void*)"thread-new");pthread_t tid2;pthread_create(&tid2,NULL,gopthread,(void*)"thread-new");pthread_t tid3;pthread_create(&tid3,NULL,gopthread,(void*)"thread-new");while(1){sleep(5);printf("main thread running...,pid==%d\n",getpid());printf("new thread running...,pid==%d, gval==%d,&gval==%p\n",getpid(),gval,&gval);}return 0;
}

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

用途

虽然线程一直是在共享数据,但是也有一部分自己的资源

线程中私有的部分包括:一组寄存器(硬件上下文数据---线性可以动态运行)、栈(线程在运行的时候,会形成各种临时变量,临时变量会被每个线程保存在自己的栈区)、线程ID、errno、信号屏蔽字、调度优先级

进程的多个线程共享同一地址空间,因此Text Segment、Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个全局变量,在各线程中都可以访问到,除此之外,各线程还共享以下进程资源和环境

文件描述符表

每种信号的处理方式(SIG_ IGN、SIG_ DFL或者自定义的信号处理函数)

当前工作目录

用户id和组id

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MOE论文详解(3)-Switch Transformers

Switch Transformers也是google在2022年发表的一篇论文, 该论文简化了MoE的路由算法, 减少了计算量和通信量; 第一次支持bfloat16精度进行训练. 基于T5-Base和T5-Large设计的模型在相同的算力下训练速度提升了7x倍; 同时发布了1.6万亿(1.6 trillion)参数的MoE模型&#xff0c;相…

【Next.js 项目实战系列】03-查看 Issue

原文链接 CSDN 的排版/样式可能有问题&#xff0c;去我的博客查看原文系列吧&#xff0c;觉得有用的话&#xff0c;给我的库点个star&#xff0c;关注一下吧 上一篇【Next.js 项目实战系列】02-创建 Issue 查看 Issue 展示 Issue​ 本节代码链接 首先使用 prisma 获取所有…

【QT】常用控件(二)

个人主页~ 常用控件&#xff08;一&#xff09;~ 常用控件 三、按钮类控件1、Push Buttonwidget.hwidget.cpp 2、Radio Button3、Check Box 四、显示类控件1、label 三、按钮类控件 1、Push Button QPushButton继承自QAbstractButton&#xff0c;它是所有按钮的父类 我们从…

线下陪玩导游系统软件源码,家政预约服务源码(h5+小程序+app)

游戏陪玩系统源码陪玩小程序源码搭建基于PHP&#xff0b;MySQL陪玩系统app源码陪玩系统定制开发服务、成品陪玩系统源码 系统基于Nginx或者Apache PHP7.3 数据库mysql5.6 前端为uniapp-vue2.0 后端为thinkphp6 有域名授权加密&#xff0c;其他开源可二开 演示源码下载 开…

Zookeeper快速入门:部署服务、基本概念与操作

文章目录 一、部署服务1.下载与安装2.查看并修改配置文件3.启动 二、基本概念与操作1.节点类型特性总结使用场景示例查看节点查看节点数据 2.文件系统层次结构3.watcher 一、部署服务 1.下载与安装 下载&#xff1a; 一定要下载编译后的文件&#xff0c;后缀为bin.tar.gz w…

如何匿名浏览网站,保护在线隐私?

在现如今的网络世界&#xff0c;在线隐私已不复存在。你总是被跟踪&#xff0c;即使你使用隐身模式也无济于事。隐身模式会阻止浏览器保存你的浏览历史记录。但它并不能阻止你的互联网服务提供商 (ISP)、雇主、学校、图书馆或你访问的网站看到你在网上做什么。 更有不法分子在未…

CVE-2015-4852 Weblogic T3 反序列化分析

0x01 前言 看到很多师傅的面经里面都有提到 Weblogic 这一个漏洞&#xff0c;最近正好有一些闲暇时间&#xff0c;可以看一看。 因为环境上总是有一些小问题&#xff0c;所以会在本地和云服务器切换着调试0x02 环境搭建 • 太坑了&#xff0c;我的建议是用本地搭建的方法&…

【C语言】一维数组应用Fibonacci数列

Fibonacci数&#xff08;斐波那契数列&#xff09; 前两项为1&#xff0c;从第三项开始&#xff0c;每一项为前两项的和。可以知道连续三项的关系&#xff1a;f[i]f[i-1]f[i-2] 使用数组进行存储&#xff0c;十分方便。可以知道前n项的fibonacci数。 #include <stdio.h>…

ios局域网访问主机Xcode配置

前景&#xff1a; 公司业务是做智能家居&#xff0c;所有设备通过主机控制&#xff0c;目前有个产品需求是&#xff0c;在没有外网的情况下依然能够通过局域网控制主机的设备。 IOS开发需要做的&#xff1a; 除了业务代码之外&#xff0c;前提还要配置访问局域网功能。有以下…

诺贝尔经济学奖历史名单数据集(1969-2024年)

2024年诺贝尔经济学奖授予了达龙阿西莫格鲁&#xff08;Daron Acemoglu&#xff09;、西蒙约翰逊&#xff08;Simon Johnson&#xff09;和詹姆斯A罗宾逊&#xff08;James A. Robinson&#xff09;&#xff0c;以表彰他们在理解制度如何影响经济发展方面的贡献。&#xff08;“…

Linux 外设驱动 应用 3 串口

3 串口 3.1 串口原理 串行口是计算机一种常用的接口&#xff0c;具有连接线少&#xff0c;通讯简单&#xff0c;得到广泛的使用。常用的串口是 RS- 232-C接口(又称 EIA RS-232-C)它是在 1970 年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同…

Input-Source-Pro:自动切换输入法并提示状态

Input Source Pro 是一款 macOS 上的输入法辅助工具&#xff0c;它可以根据不同应用、不同网站来自动切换输入法&#xff0c;并可以在鼠标周围显示当前输入法状态。 macOS 不像 Windows 那样能保存输入法状态&#xff0c;因此这样的软件还是挺有用的。 ‍ 介绍 官网&#x…

OceanBase中扩容OCP节点step by step

许多用户在开始使用OceanBase时部署OCP&#xff0c;通常选择单节点部署。但随着后续业务规模的不断扩大&#xff0c;会开始担忧单节点OCP在面对故障时可能丧失对集群运维管控的连续性。鉴于此&#xff0c;会将现有的单节点OCP扩展至多节点部署&#xff0c;以此来确保OCP服务的高…

『Mysql集群』Mysql高可用集群之读写分离(二)

前言 主从复制: 解决了Mysql的单点故障问题以及提高MySQL的整体服务性能. 读写分离: 解决的是数据库的读性能问题,分担主库的压力&#xff0c;提高系统的可用性和稳定性。 分库分表: 数据库分表可以解决单表海量数据的查询性能问题&#xff0c;分库可以解决单台数据库的并发…

计算机网络——应用层(DNS域名系统、文件传输协议FTP、远程终端协议TELNET、万维网)

应用层概述 不同网络应用的应用进程之间&#xff0c;还需要用不同的通信规则。因此在运输层协议之上&#xff0c;还需要有应用层协议。 每个应用层协议都是为了解决某一类应用问题&#xff0c;而问题的解决又必须通过位于不同主机中的多个应用进程之间的通信和协同工作来完成。…

网络七层架构

目录标题 网络七层架构从正确认识网络七层架构开始 网络七层架构 简介&#xff1a; 网络七层架构是指ISO/OSI模型&#xff0c;它是国际标准化组织&#xff08;ISO&#xff09;制定的一种用于计算机网络体系结构的参考模型。该模型将计算机网络的功能划分为七个层次&#xff0c…

Spring Boot知识管理:跨平台集成方案

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

【UML】一个UML学习的还不错的几个帖子

https://segmentfault.com/a/1190000042775634 寂然解读设计模式 - UML类图&类的六大关系-阿里云开发者社区

信息抽取数据集处理——RAMS

引言 RAMS数据集&#xff08;RAMS&#xff1a;Richly Annotated Multilingual Schema-guided Event Structure&#xff09;由约翰斯霍普金斯大学于2020年发布&#xff0c;是一个以新闻为基础的事件抽取数据集。它标注了9,124个事件&#xff0c;涵盖了139种不同的事件类型和65种…

客户案例 | Ansys与台积电和微软合作加速光子仿真

Ansys与台积电和微软展开合作&#xff0c;将硅光子器件的仿真和分析速度提高10倍以上 主要亮点 借助使用NVIDIA图形处理单元&#xff08;GPU&#xff09;的Microsoft Azure虚拟机&#xff0c;Ansys Lumerical™ FDTD 3D电磁仿真的光子器件仿真速度实现了10倍提升 凭借Azure云…