Linux入门之多线程|线程|进程基本概念及库函数

news2024/11/27 0:44:17


目录

一、线程

1.线程的概

补充知识点:页表

2.线程的优点

3.线程的缺点

4.线程异常

5.线程用途

二、线程与进程的区别与联系

三、关于进程线程的问题

0.posix线程库

1.创建线程

2.线程终止

3.取消线程

4.线程等待(等待线程结束)


一、线程

1.线程的概念

  • 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是一个进程内部的控制序列
  • 一切进程至少有一个线程
  • 线程在进程内部运行,本质是在进程的地址空间内运行
  • 在linux系统中,从cpu看到,进程包括进程pcb,地址空间,页表等。看到的线程只有pcb
  • 透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成线程执行流

        线程是一个执行分支,执行粒度比进程更细,调度成本更低,这里的调度成本就是不用切换pcb,切换cache等

        从内核角度来看,线程是cpu调度的基本单元,进程是承担分配系统资源的基本实体

  • 对于cpu来说,无法区分进程/线程,cpu内部包含:运算器,控制器,寄存器,MMU,硬件cache(高速缓存)l1,l2,l3。
  • 对于一个进程来说,里面可能存在多个线程,os需要对这些线程管理,创建一个线程控制块(TCB),TCB属于PCB,在windows中确实是这样干的,但是在linux中,用pcb来模拟tcb,复用了进程的代码和结构,更好维护,效率更高,这也就解释了为什么linux可以不间断的运行。在实际运行中,os系统使用最频繁的功能除了os本身,接下来就是进程。linux没有真正意义上的线程。
  • 进程在调度的时候,用pid来识别,线程调度的时候,用lwp来识别。

补充知识点:页表

前面有写过页表是kv结构的,里面包含虚拟地址以及映射到真实物理内存的地址,还包括其他属性。

物理内存不是按字节划分的,如果按字节划分,频繁的操作io,注定过多的寻址,就会导致过多的机械运动,所以效率十分低下,所以os和磁盘设备进行交互的时候,是按块为单位。所以物理内存是按块划分的(4KB),每个块称为页page。内存管理的本质就是将磁盘中特定的4KB块(数据内容)放到一个物理内存的4KB空间。os对物理内存也有自己的管理方式,里面存储每块的属性。

为什么要以块为单位?

1.文件系统+编译器 文件在磁盘的时候,就是以块为单位(4KB)

2.os+内存:内存在实际进行内存管理,也是以4kb为单位

3.局部性原理的特性:允许我们提前加载正在访问数据的相邻或者附近的数据

我们会通过预先加载要访问的数据的附近数据来减少未来io的次数,多加载进来的数据本质上就叫做数据的预加载。

为什么要以4KB为单位

1.IO的基本单位(内核内存+文件系统)

2.通过局部性原理 预测未来的命中情况 提高效率

虚拟地址空间有32位,难道页表需要2^32byte吗?NO

实际上虚拟地址是按照10+10+12来划分的,首先高10位,找到第一级页表(页目录),kv找到第二级的页表(中间10位地址在这个页表内kv)找到物理内存对应页框的起始地址,最后用虚拟地址的后12位对应的数据地址找到页内偏移,即采用基地址+偏移量的方法,在物理内存中定位任意一个内存字节的位置

  • 在实际申请malloc的时候,os只在虚拟地址空间上申请就行了,在真正访问的时候,进程发现了这个kv关系不存在,触发缺页中断,os才会去申请或者填充页表,并申请具体的物理内存。
  • 看下面一段代码:
char *s  = "hello";
*s = 'h';

s是一个指针,指向字符常量区,现在对s进行修改,在语言层面上,会中断进程。

从内核角度:s里保存的是指向字符的虚拟起始地址,*s进行寻址的时候,需要进行虚拟地址向物理地址进行转换,使用MMU+页表的方式,此时os对进程的操作进行审查,虽然可以找到这个地址,但是操作是非法的,此时mmu异常,os识别异常转换为信号,发送给目标进程,目标进程在从内核态转为用户态的时候,进行信号处理,终止进程。

2.线程的优点

  • 创建一个新的线程比新的进程代价要小很多
  • 与进程切换相比,切换线程的工作os要做的工作少很多
  • 线程占用的资源比进程少很多
  • 能够充分利用多处理器的可并行数量
  • 在等待慢速I/O结束的同时,程序可以执行其他的计算任务
  • 计算密集型应用,如,加密解密,文件压缩解压等,可以分解到多个线程实现。
  • IO密集型应用,如上传下载,需要等待磁盘和网络带宽,线程可以同时等待不同的IO操作。

3.线程的缺点

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

4.线程异常

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

5.线程用途

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

二、线程与进程的区别与联系

  • 线程共享进程数据,但是也拥有自己的一部分数据:线程id,一组寄存器,errno,信号屏蔽字,调度优先级
  • 线程共享以下进程的资源和环境:文件描述符表fd,每种信号的处理方式(默认或者自定义),当前工作目录,用户id和组id

三、关于进程线程的问题

之前学习的单进程,就可以看成是具有一个线程执行流的进程

0.posix线程库

  • 与线程有关的函数pthread_t
  • 使用库函数,引入头文件<pthread.h>
  • makefile里链接这些线程函数库要使用编译器命令的 -lpthread选项

1.创建线程

int pthread_create(pthread_t *thread,const pthread_attr_t * attr, void *(start_routine)(void *),void * arg);

参数:
thread:返回线程的ID
attr:设置线程属性,一般null为默认属性
start_routine:函数地址,线程启动后要执行的函数
arg:传给线程启动函数的参数

返回值:成功返回0,失败返回错误码

2.线程终止

线程终止有3种方法:

  1. 从线程函数return ,这种方法对主线程不适用,从main函数里return相当于exit
  2. 线程调用pthread_exit终止自己
  3. 一个线程可以调用pthread_cancel终止同一个进程中的另一个线程
void pthread_exit(void * value_ptr);
参数:
value_ptr不要指向一个局部变量
返回值:
无返回值,跟进程相同,线程结束的时候无法返回到它的调用者

注意:pthread_exit或者return返回的指针所指向的内存单元必须是全局的,或者malloc分配的,不能在线程函数的栈上分配,因为当其他线程得到这个返回指针时,线程函数已经退出了

3.取消线程

int pthread_cancel(pthread_t thread);
//thread:线程id
//成功返回0,失败返回错误码

4.线程等待(等待线程结束)

  • 已经退出的线程,其空间没有被释放,仍在进程的地址空间内(类似于僵尸进程)
  • 创建新的线程不会复用刚才退出线程的地址空间
int pthread_join(pthread_t thread,void ** value_ptr);
//thread 线程Id
//value_ptr:指向一个指针, void* * ,指向线程的返回值
//返回值:成功0,失败返回错误码

调用该函数的线程将挂起等待,知道id为thread的线程终止。thread线程以不同的方法终止,通过pthread_join得到的终止状态不同

  1. 线程return返回,value_ptr指向的单元存放的是线程函数的返回值
  2. pthread_cancel异常终止,存放PTHREA_CANCLED
  3. 自己调用pthread_exit终止,存放pthread_exit()中的参数
  4. 对thread终止状态不感兴趣,可以传递null

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

02|李沐动手学深度学习v2(笔记)

基础优化算法 导航 基础优化算法梯度下降1.1 小批量随机梯度下降1.2 小结 线性回归实现1. 处理数据1.3 生成大小为batch_size的小批量 2. 处理模型3. 模型评估4. 训练过程 梯度下降 针对我们的模型没有显示解。&#xff08;生活中很少能有完全符合的线性模型&#xff0c;大多数…

用户中心笔记-leovany

1. 安装 官方地址&#xff1a;https://pro.ant.design/zh-CN/docs/getting-started 1.1 Mac系统 1.1.1 安装yarn 安装yarn brew install yarn查看版本 brew -v 1.1.2 安装node // 安装node brew install node // 关联 brew unlink node && brew link node // 查看版…

信息系统安全运维模型 课堂记录

声明 本文是学习 信息系统安全运维管理指南. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 范围 本标准描述了信息系统安全运维管理体系&#xff0c;给出了安全运维策略、安全运维组织、安全运维规程和安全运维支撑系统等方面相关活动的目的、要求和…

【项目 计网9】4.25 IO多路复用简介 4.26select API介绍 4.27 select代码编写

文章目录 4.25 IO多路复用&#xff08;I/O多路转接&#xff09;简介4.26select API介绍4.27 select代码编写客户端程序select程序select的缺点 4.25 IO多路复用&#xff08;I/O多路转接&#xff09;简介 输入输出&#xff1a;以内存为主体 读写&#xff1a;以程序为主体 程序要…

2023-09-03 LeetCode每日一题(消灭怪物的最大数量)

2023-09-03每日一题 一、题目编号 1921. 消灭怪物的最大数量二、题目链接 点击跳转到题目位置 三、题目描述 你正在玩一款电子游戏&#xff0c;在游戏中你需要保护城市免受怪物侵袭。给你一个 下标从 0 开始 且长度为 n 的整数数组 dist &#xff0c;其中 dist[i] 是第 i …

从一到无穷大 #12 Planet-Scale In-Memory Time Series Database, Is it really Monarch?

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言约束优势数据模型写路径查询路径Field Hints Index可靠性 其他总结 引言 Monarc…

Thymeleaf常见属性

参考文档 thymeleaf 语法——th:text默认值、字符串连接、th:attr、th:href 传参、th:include传参、th:inline 内联、th:each循环、th:with、th:if_猎人在吃肉的博客-CSDN博客 代码演示 Controller public class TestController {AutowiredMenuService menuService;GetMapp…

基于多设计模式下的同步异步日志系统

基于多设计模式下的同步&异步日志系统 代码链接&#xff1a;https://github.com/Janonez/Log_System 1. 项目介绍 本项目主要实现一个日志系统&#xff0c; 其主要支持以下功能&#xff1a; 支持多级别日志消息支持同步日志和异步日志支持可靠写入日志到标准输出、文件…

uni-app之android原生插件开发

一 插件简介 1.1 当HBuilderX中提供的能力无法满足App功能需求&#xff0c;需要通过使用Andorid/iOS原生开发实现时&#xff0c;可使用App离线SDK开发原生插件来扩展原生能力。 1.2 插件类型有两种&#xff0c;Module模式和Component模式 Module模式&#xff1a;能力扩展&…

S32K324芯片学习笔记

文章目录 Core and architectureDMASystem and power managementMemory and memory interfacesClocksSecurity and integrity安全与完整性Safety ISO26262Analog、Timers功能框图内存mapflash Signal MultiplexingPort和MSCR寄存器的mapping Core and architecture 两个Arm Co…

数学建模:Yalmip求解线性与非线性优化问题

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 线性优化 使用 Yalmip 求解线性规划最优值&#xff1a; m i n { − x 1 − 2 x 2 3 x 3 } x 1 x 2 ⩾ 3 x 2 x 3 ⩾ 3 x 1 x 3 4 0 ≤ x 1 , x 2 , x 3 ≤ 2 \begin{gathered}min\{-x_1-2x_23x_3\} \…

networkX-01-基础

文章目录 创建一个图1. 节点方式1 &#xff1a;一次添加一个节点方式2&#xff1a;从list中添加节点方式3&#xff1a;添加节点时附加节点属性字典方式4&#xff1a;将一个图中的节点合并到另外一个图中 2. 边方式1&#xff1a;一次添加一条边方式2&#xff1a;列表&#xff08…

23062网络编程day2

1. TCP的服务器 客户端的代码 服务器 #include <myhead.h>#define ERR_MSG(msg) do{\fprintf(stderr,"__%d__:",__LINE__);\perror(msg);\ }while(0)#define PORT 8888#define IP "192.168.114.104"int main(int argc, const char *argv[]) {//创建…

大数据技术原理与应用学习笔记第1章

黄金组合访问地址&#xff1a;http://dblab.xmu.edu.cn/post/7553/ 1.《大数据技术原理与应用》教材 官网&#xff1a;http://dblab.xmu.edu.cn/post/bigdata/ 2.大数据软件安装和编程实践指南 官网林子雨编著《大数据技术原理与应用》教材配套大数据软件安装和编程实践指…

Windows 操作系统下 Python 及其模块的管理

Python 是一款解释型语言&#xff0c;理论上一个.py文件可以当成一个稍微复杂一些的字符串指令集本文不涉及jupyter,VS,VScode,Pycharm 等集成开发环境&#xff0c;这不是我们这篇文章所关心的东西 这篇文章面向的是Python 的初学者 最近没有写太多长文章&#xff0c;多写几篇&…

8、暴力递归

前缀树 一个字符串类型的数组arr1,另一个字符串类型的数组arr2。arr2中有哪些字符,是arr1中出现的?请打印。arr2中有哪些字符,是作为arr1中某个字符串前缀出现的?请打印。arr2中有哪些字符,是作为arr1中某个字符串前缀出现的?请打印 arr2中出现次数最大的前缀 public…

LabVIEW开发超导体电流特性的测量系统

LabVIEW开发超导体电流特性的测量系统 超导体的临界电流密度Jc不断增加&#xff0c;目前超导线已达到150MA/cm2因此&#xff0c;由于电流能力增强&#xff0c;超导体被认为应用于电力系统&#xff0c;例如传输电缆、超导磁体和超导磁储能。由于Jc是此类应用的重要值&#xff0…

STM32F4X RNG随机数发生器

STM32F4X RNG随机数发生器 随机数的作用STM32F4X 随机数发生器RNG控制寄存器RNG状态寄存器RNG数据寄存器RNG数据步骤RNG例程 随机数的作用 随机数顾名思义就是随机产生的数字&#xff0c;这种数字最大的特点就是其不确定性&#xff0c;你不知道它下一次产生的数字是什么。随机…

差分数组/前缀和

文章目录 1094. 拼车1109. 航班预定统计303. 区域和检索 - 数组不可变560. 和为K的子数组523. 连续的子数组的和 1094. 拼车 class Solution {public boolean carPooling(int[][] trips, int capacity) {int[] diff new int[1001]; // 记录每个站点改变的人数&#xff0c;比如…

c语言---指针

指针 前言 记录一个数据对象在内存中的存储位置&#xff0c;需要两个信息&#xff1a; 1、数据对象的首地址。 2、数据对象占用存储空间大小 基础数据类型所占内存空间大小&#xff08;字节&#xff09;&#xff0c;一个字节代表8个二进制位 char 1 short 2 int 4 lon…