linux线程的认识

news2024/11/5 9:03:11

1.虚拟地址空间

管理进程的pcb结构体task_struct中有一个mm_struct指针,指向虚拟地址空间,而编译好的代码中有地址,但是是虚拟地址,那么虚拟地址是怎么转化成真实的物理地址呢?通过页表转化

我们知道,代码中的地址都是虚拟地址,每行代码都有对应的地址,比如一个函数,可能是连续的代码地址,构成代码块,也就是说,一个函数对应一批连续的虚拟地址,那么,我们把10个函数拆分一下,可不可以呢?在技术上是可以实现的,我们就有了线程的出现,

物理内存

OS进行内存管理,不是以字节为单位的,而是以内存块为单位的,默认大小是4KB,操作系统和磁盘文件进行IO的基本单位是4KB,对于磁盘来说就是8个扇区,而在内存中,每4KB大小内存,叫做页块或页帧,内存是由一个个页框组成的,

2.线程的概念

线程在进程内部运行,是CPU调度的基本单位

我们以前理解的进程 进程=内核数据结构+代码和数据 ,在内核观点看来,进程是承担分配操作系统资源的实体

而线程就是task_strust,(大概是这样的,不太准确),

linux中没有管理线程的结构体,而是用task_struct模拟线程,在linux中,他们都是执行流,叫做轻量级进程

2.1 什么是线程

  • 线程是一个进程内部的控制序列
  • 每个进程都至少有一个线程
  • 线程在进程内部运行,本质上是在进程地址空间运行
  • 通过进程虚拟地址空间可以看到进程的大部分资源,将进程资源合理的分配给每个执行流,就形成了线程执行流

2.2 线程的优点

  • 创建一个新线程要比创建一个进程代价小的多,为什么?

因为进程有进程虚拟地址空间,而代码和数据在内存中,在执行一个进程时,cpu会把经常用到的代码(比如循环中的代码)加载到cpu中的cache快速储存器中,这样执行代码时效率会比较快,而如果我们创建一个进程,那么cpu中的cache也要重新加载代码,这样代价就比较大了,而创建一个线程,只需要创建一个task_struct,虚拟地址空间还是原来的,只需要映射的时候改动一下,所以说线程的创建代价比较小

  • 线程占用的资源要比进程小很多
  • 能充分利用多处理器的可并行数量
  • 计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现
  • I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作

2.3 线程的缺点

线程不具有健壮性,也就是说,一个线程出问题了,那么整个进程都要被杀掉,或者在一个多线程进程中,因为时间分配上的偏差,导致因为共享了不该共享的变量而造成不良影响,也就是说,线程是缺乏保护的,

2.4线程共享的数据

线程ID 一组寄存器 栈 errno 信号屏蔽字 调度优先级

每个线程都有自己的栈空间,用于存储局部变量、函数参数和返回地址等

每个线程在执行时都有自己的寄存器状态,说明线程可以动态运行,也就是多线程可以并发执行

2.5 使用线程

#include<iostream>
#include<unistd.h>
#include<ctime>

void* threadStart(void* args)
{
    while(true)
    {
        sleep(1);
        std::cout << "new thread running..." << ", pid: " << getpid()<< std::endl;
    }
}
int main()
{
    srand(time(nullptr));
    //创建一个线程
    pthread_t tid;
    pthread_create(&tid,nullptr,threadStart,(void*)"thread-new");

    //主线程
    while(true)
    {
        std::cout<<"main thread running... "<<", pid: "<<getpid()<<std::endl;
        sleep(1);
    }

    return 0;
}

3.线程的控制

对于linux来说,没有线程,只有轻量级进程(就是线程),在linux中对轻量级进程进行分装,系统调用只会给上层用户提供创建轻量级进程的接口,而其他接口操作系统是不提供的,但是他提供了线程库,通过线程库,我们可以创建线程,终止线程,调用线程,等待线程

所以我们在编译使用线程的代码时,要链接线程库

g++ -o testthread testthread.cc -std=c++11 -lpthread

关于线程控制的几个问题

  1. 主线程和新线程谁先运行? 不确定,顺序可能发生变化
  2. 主线程应该最后退出
  3. 线程函数传参,我们可以传任何类型,类对象也可以
  4. 线程函数返回,只考虑正确的返回,因为线程出现异常,那么整个进程就退出了
  5. 新线程可以使用return结束,或者pthread_exit结束线程
  6. 一个线程被创建,默认是必须被join的,但是如果一个线程处于分离状态,就可以不用join了

关于线程的一些函数

pthread_create

int pthread_create(pthread_t*  tidp, const pthread_attr_t*  attr,
                   void* (*start_rtn)(void*), void*  arg);

pthread_create函数用于创建一个新线程

  • void* (*start_rtn)(void*):线程函数的指针,即新线程将从这个函数开始执行。
  • void* restrict arg:传递给线程函数的参数。如果没有参数,则设为 NULL
  • 成功时返回0,失败时返回错误码

pthread_join

int pthread_join(pthread_t thread, void **retval);

pthread_join用于等待指定的线程结束

  • pthread_t thread:要等待的线程的ID。
  • void **retval:一个指向 void* 类型的指针的指针,用于存储线程的返回值。如果不需要线程的返回值,可以传递 NULL
  • 成功时返回0,失败时返回错误码。
  • pthread_join函数会阻塞调用他的线程,直到指定的线程结束

pthread_exit

void pthread_exit(void *retval);

pthread_exit用于结束当前线程

  • void *retval:一个指向线程返回值的指针。这个值会被主线程或其他线程通过 pthread_join 函数获取。
  • pthread_exit 函数不会返回。一旦调用,当前线程将终止。
  • 传递给 pthread_exit 的值可以被等待该线程的主线程或其他线程通过 pthread_join 函数获取。

pthread_cancel

int pthread_cancel(pthread_t thread);

pthread_cancel函数用于请求取消指定的线程

  • pthread_t thread:要取消的线程的ID。
  • 成功时返回0,失败时返回错误码。

pthread_detach

int pthread_detach(pthread_t thread);

pthread_detach 将一个线程设置为分离状态(detached state)。分离线程在结束执行时不会留下任何需要清理的资源,因此不需要其他线程调用 pthread_join 来等待它结束和回收资源。

  • pthread_t thread:要设置为分离状态的线程的ID。
  • 成功时返回0,失败时返回错误码。
  • 一个线程只能被设置为分离状态一次,一旦线程被分离,它不能再被 pthread_join

pthread_self

pthread_t pthread_self(void);
  • 不需要任何参数,并且返回调用它的线程的线程ID。
  • 返回当前线程的 pthread_t 类型的线程ID

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

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

相关文章

05 Django 框架模型介绍(一)

文章目录 1、Django 模型简介2、Django 中创建并使用模型&#xff08;1&#xff09;新加一个名为 myapp 的应用&#xff08;2&#xff09;定义模型类&#xff08;2&#xff09;激活模型类&#xff08;3&#xff09;创建数据库迁移文件&#xff08;4&#xff09;应用迁移文件 3、…

Autosar CP中的I/O硬件抽象层功能与接口使用导读

规范的主要内容 I/O硬件抽象层&#xff08;I/O Hardware Abstraction Layer&#xff0c;简称IoHwAb&#xff09;的主要功能包括以下几点&#xff1a; 提供硬件访问接口&#xff1a;I/O硬件抽象层为上层软件组件&#xff08;如应用层软件&#xff09;提供访问微控制器硬件&…

【毫米波雷达(三)】汽车控制器启动流程——BootLoader

汽车控制器启动流程——BootLoader 一、什么是Bootloader(BT)&#xff1f;二、FBL、PBL、SBL、ESS的区别三、MCU的 A/B分区的实现 一、什么是Bootloader(BT)&#xff1f; BT就是一段程序&#xff0c;一段引导程序。它包含了启动代码、中断、主程序等。 雷达启动需要由BT跳转到…

初始JavaEE篇——多线程(8):JUC的组件

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 目录 Callable接口 ReentrantLock synchronized 与 ReentrantLock的区别 信号量&#xff08;Semaphore&#xff09; CountDown…

Vue3+Data-V实现可视化大屏页面布局

目录 一、前言 二、环境准备 1.Vue3安装npm create vuelatest 2.Data-V配置 项目Data-v安装 main.js中注册Data-v到全局 ​编辑可使用按需引入 3.测试 三、导航栏路由跳转配置 1.子组件mainNav组件准备 2.父组件准备导航栏参数传递 3.子组件接收父组件参数 4.导航…

Solana 代币 2022 — Transfer Hook

从零到英雄的 Solana 代币 2022 — Transfer Hook Token 2022 计划引入了几项令人兴奋的扩展&#xff0c;增强了铸造和代币账户的功能。在这些功能中&#xff0c;我个人最喜欢的是Transfer Hook &#xff08;转账钩子&#xff09; 。 想象时间 让我们戴上想象的帽子&#xf…

Edge浏览器设置优化

依次点击右上角的三个点-“设置”。 在“外观”设置项中&#xff0c;关闭“显示选项卡操作菜单”、“在垂直选项卡中隐藏标题栏”、“在标题栏中显示个人资料图标”&#xff0c;选择“不显示独立搜索框”。 在“选择要在工具栏上显示的按钮”&#xff0c;开启“下载按钮”。 重…

电脑软件:推荐一款免费且实用的电脑开关机小工具

目录 一、软件简介 二、软件功能 三、软件特点 四、使用说明 五、软件下载 今天给大家推荐一款免费且实用的电脑开关机小工具KShutdown&#xff0c;有需要的朋友可以下载试一下&#xff01; 一、软件简介 KShutdown是一款精巧且实用的定时自动关机小工具&#xff0c;对于…

Python Matplotlib 子图绘制

Python 中的子图绘制 在数据可视化中&#xff0c;展示多个图表在同一个画布上是常见的需求&#xff0c;这样可以更直观地比较不同数据集之间的关系。Python 中的 Matplotlib 库为我们提供了强大的功能来实现这一点。在本篇文章中&#xff0c;我们将详细介绍如何使用 Matplotli…

透明加密技术是什么?透明加密技术的原理与应用实践(内含代表性软件分享)

触目惊心&#xff01;10大典型间谍案例回顾 张某离职前搜集大量文件资料&#xff0c;甚至拆开电脑主机拷贝文件 私自存有5200份文件资料 其中标注绝密级的59份 机密级848份 秘密级541份 在当今这个信息化高速发展的时代&#xff0c;透明加密技术已不容忽视。那么&#xff…

rhce:web服务器

web服务器简介 服务器端&#xff1a;此处使用 nginx 提供 web 服务&#xff0c; RPM 包获取&#xff1a; http://nginx.org/packages/ /etc/nginx/ ├── conf.d #子配置文件目录 ├── default.d ├── fastcgi.conf ├── fastcgi.conf.default ├── fastcgi_params #用…

后端:Spring、Spring Boot-实例化Bean依赖注入(DI)

文章目录 1. 实例化Bean2. 使用FactoryBean3. 依赖注入(DI)3.1 AutoWired 属性注入(查找顺序&#xff1a;先类型&#xff0c;后名字)3.2 AutoWired 在构造函数&参数上的使用3.3 Inject和Resource 进行依赖注入3.4 Value 进行注入 1. 实例化Bean 默认使用无参构造函数&…

Android——横屏竖屏

系统配置变更的处理机制 为了避免横竖屏切换时重新加载界面的情况&#xff0c;Android设计了一中配置变更机制&#xff0c;在指定的环境配置发生变更之时&#xff0c;无需重启活动页面&#xff0c;只需执行特定的变更行为。该机制的视线过程分为两步&#xff1a; 修改 Androi…

ubuntu openmpi安装(超简单)

openmpi安装 apt update apt install openmpi-bin openmpi-common libopenmpi-dev安装到此完毕 测试一下&#xff0c;success !

基于DCT的数字水印算法

摘要 数字水印技术近年来得到了较大的发展&#xff0c;基于变换域的水印技术是目前研究的热点。数字水印是利用数字作品中普遍存在的冗余数据和随机性&#xff0c;把标识版权的水印信息嵌入到数字作品中&#xff0c;从而可以起到保护数字作品的版权或其完整性的一种技术。 一个…

【Linux指令】---获取进程的PID

获取进程的PID getpid()函数

李红《复变函数与积分变换》第五版课后习题答案PDF

《复变函数与积分变换(第五版)学习辅导与习题全解》是与《复变函数与积分变换(第五版)》(华中科技大学数学与统计学院)配套的学习辅导书&#xff0c; 全书共八章&#xff1a;复数与复变函数&#xff0c; 解析函数&#xff0c;复变函数的积分&#xff0c; 解析函数的级数表示&am…

Zypher Network:全栈式 Web3 游戏引擎,服务器抽象叙事的引领者

近期&#xff0c;《黑神话&#xff1a;悟空》的爆火不仅让 AAA 游戏重回焦点&#xff0c;也引发了玩家与开发者的热议。Web2 游戏的持续成功导致部分 Web3 玩家们的倒戈&#xff0c;对比之下 Web3 游戏存在生命周期短且商业模式难以明确的问题&#xff0c;尤其在当前加密市场环…

【Linux】利用 <信号量> 实现 <生产者-消费者模型-线程同步 >(思维导图&代码演示&思路解析)

前言 大家好吖&#xff0c;欢迎来到 YY 滴Linux系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Lin…

「Mac畅玩鸿蒙与硬件20」鸿蒙UI组件篇10 - Canvas 组件自定义绘图

Canvas 组件在鸿蒙应用中用于绘制自定义图形,提供丰富的绘制功能和灵活的定制能力。通过 Canvas,可以创建矩形、圆形、路径、文本等基础图形,为鸿蒙应用增添个性化的视觉效果。本篇将介绍 Canvas 组件的基础操作,涵盖绘制矩形、圆形、路径和文本的实例。 关键词 Canvas 组件…