线程的理解及基本操作

目录

一、线程的理解

(1)什么是线程呢?

(2)线程的优缺点及异常

二、线程的基本操作

(1)创建一个新的进程

    (2)获取线程id

(3)线程终止

(4)取消一个线程

(5)线程等待

(6)线程分离

三、gettid和pthread_self的区别


一、线程的理解

(1)什么是线程呢?

        在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列/一个执行流”,一切进程至少都有一个执行线程。
        线程在进程内部运行,本质是在进程地址空间内运行
        在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化
        透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。

        从这张图中我们可以看到,Linux中其实是没有真正的线程的。Linux中的线程是对进程代码的复用,即在内核中复用进程pcb,作为线程的pcb(tcb),然后让这些pcb都指向一段相同的地址空间,再通过线程库的封装,给用户层营造了操作系统中的线程。

(2)线程的优缺点及异常

优点

缺点

异常

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

(3)线程和进程的一些差别

        1.进程是资源分配的基本单位
        2.线程是调度的基本单位
        3.线程共享进程数据,但也拥有自己的一部分数据:
                线程ID,一组寄存器,栈,errno,信号屏蔽字,调度优先级

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

二、线程的基本操作

(1)创建一个新的进程

参数
        thread:返回线程ID
        attr:设置线程的属性,attr为NULL表示使用默认属性
        start_routine:是个函数地址,线程启动后要执行的函数
        arg:传给线程启动函数的参数
返回值:成功返回0;失败返回错误码

    (2)获取线程id

        pthread_ create函数会产生一个线程ID,存放在第一个参数指向的地址中。该线程ID和前面说的线程ID不是一回事。
        前面讲的线程ID属于进程调度的范畴。因为线程是轻量级进程,是操作系统调度器的最小单位,所以需要一个数值来唯一表示该线程。
        pthread_ create函数第一个参数指向一个虚拟内存单元,该内存单元的地址即为新创建线程的线程ID,属于NPTL线程库的范畴。线程库的后续操作,就是根据该线程ID来操作线程的。
线程库NPTL提供了pthread_ self函数,可以获得线程自身的ID:

        从这里的结果可以看到这个线程id是一个非常大的数,和我们之前所说的进程id完全不一样,进程id是操作系统中维护的一个id,二线程id是线程库维护的一个id,这个id其实就是该线程描述结构体在地址空间中的起始地址。

        pthread_t 到底是什么类型呢?取决于实现。对于Linux目前实现的NPTL实现而言,pthread_t类型的线程ID,本质就是一个进程地址空间上的一个地址。

        我们知道一个动态库被使用的时候需要被加载到进程地址空间的共享区中,pthread动态库也不例外。在创建一个新的线程的时候,操作系统首先会创建一个pcb结构体来描述该线程(这是内核中的描述结构体),但是对于用户而言,不能直接访问操作系统的内容,于是有了pthread这个软件层封装了操作系统的轻量级进程,给用户看到的直接就是线程。

        而在pthread动态库中,他会维护一个类似于数组的结构,这个数组里面保存了所有线程的描述结构体tcb,里面包含了该线程的属性字段,而pthread_self函数返回的就是该描述结构体的地址!不同于操作系统内核的pid,当然这个描述结构体中一定保存了内核的pid来实现用户层和内核层的转换。

  

(3)线程终止

        线程终止的函数就好像return一样使用,只不过要注意的是,return要返回一个void*的类型,因为我们在pthread_create的时候,他的返回值就是void*类型。

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


        

(4)取消一个线程

        既然能够创建一个线程,那么必然也能取消(销毁)一个线程,这个函数无论是主线程还是其他线程都可以调用,只需要传递该线程的pthread_t参数即可。

(5)线程等待

        和进程等待一模一样,线程也需要被回收。因为Linux中的线程就是复用了进程的代码,也会产生pcb和库中的tcb,一旦没有回收,会造成内存泄漏的问题。

        值得注意的是:这里的第二个参数是一个void**类型,是一个输入输出型参数。因为pthread_create的返回值是void*类型,要想对一个void*类型进行修改需要的参数是void**类型的指针。

        调用该函数的线程将挂起等待,直到id为thread的线程终止。thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的,代码如下:

1. 如果thread线程通过return返回,value_ ptr所指向的单元里存放的是thread线程函数的返回值。
2. 如果thread线程被别的线程调用pthread_ cancel异常终掉,value_ ptr所指向的单元里存放的是常数PTHREAD_ CANCELED。
3. 如果thread线程是自己调用pthread_exit终止的,value_ptr所指向的单元存放的是传给pthread_exit的参数。
4. 如果对thread线程的终止状态不感兴趣,可以传NULL给value_ ptr参数。

5.线程的返回结果是由线程库来维护的,想要获取返回信息必须要用pthread_join函数。如果线程是分离的,则线程库不会维护其返回值,其他线程也无法通过线程库来获取其返回信息

(6)线程分离

        默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放资源,从而造成系统泄漏。
        如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源。

        一旦线程分离了,主线程再等待,返回值就不再是0

        该函数可以是线程组内其他线程对目标线程进行分离,也可以是线程自己分离。与线程终止函数使用无差。joinable和分离是冲突的,一个线程不能既是joinable又是分离的。

三、gettid和pthread_self的区别

        简单来说:gettid返回的是内核存储pcb的pid;而pthread_self返回的是线程库中的id(也就是描述结构体tcb的起始地址)。

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

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

相关文章

SpringBoot 集成RabbitMQ 实现钉钉日报定时发送功能

文章目录 一、RabbitMq 下载安装二、开发步骤:1.MAVEN 配置2. RabbitMqConfig 配置3. RabbitMqUtil 工具类4. DailyDelaySendConsumer 消费者监听5. 测试延迟发送 一、RabbitMq 下载安装 官网:https://www.rabbitmq.com/docs 二、开发步骤:…

AC的旁挂和直连的方式的使用场景

AC组网架构 AC中文含义为无线接入控制器,主要功能是可以批量配置和管理无线AP。经常工作在大中型园区网络、企业办公网络等应用场景。 下面来介绍一下无线AC的几种经典架构。 一1旁挂式组网 旁挂式组网顾名思义,就是旁挂在网络中,对AP来进行…

view design之table自定义单元格模版

View Design之table自定义单元格模版 在 columns 的某列声明 slot 后&#xff0c;就可以在 Table 的 slot 中使用参数。 slot 的参数有 3 个&#xff1a;当前行数据 row&#xff0c;当前列数据 column&#xff0c;当前行序号 index。 完整示例 <template><Table …

乘云而上,OceanBase再越山峰

一座山峰都是一个挑战&#xff0c;每一次攀登都是一次超越。 商业数据库时代&#xff0c;面对国外数据库巨头这座大山&#xff0c;实现市场突破一直都是中国数据库产业多年夙愿&#xff0c;而OceanBase在金融核心系统等领域的攻坚克难&#xff0c;为产业突破交出一副令人信服的…

在Ubuntu(Linux)系统下安装Anaconda3

1、到官网下载Linux版本的包&#xff1a;https://www.anaconda.com/download/success 2、到所在目录中&#xff0c;运行下方命令&#xff0c;Anaconda3-2024.06-1-Linux-x86_64.sh是下载包的名字 bash Anaconda3-2024.06-1-Linux-x86_64.sh输入yes确定 3、输入~/anaconda3/b…

MySQL数据库集群-PXC方案视频教程下载 MySQL架构设计及常见业务处理

MySQL数据库集群-PXC方案视频教程下载 MySQL架构设计及常见业务处理30套数据库系列Mysql/SQLServer/Redis/Mongodb/Nosql精讲训练营项目实战&#xff0c;数据库设计&#xff0c;架构设计&#xff0c;性能管理&#xff0c;集群搭建&#xff0c;查询优化&#xff0c;索引优化&…

Spring Boot植物健康系统:智慧农业的新趋势

6系统测试 6.1概念和意义 测试的定义&#xff1a;程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为&#xff1a; 目的&#xff1a;发现程序的错误&#xff1b; 任务&#xff1a;通过在计算机上执行程序&#xff0c;暴露程序中潜在的错误。 另一个…

经常聊架构模式,设计模式,编程模式,也谈谈“反模式”

在软件工程中&#xff0c;反模式&#xff08;Anti-Pattern&#xff09;是指那些表面上看起来是一个解决方案&#xff0c;但实际上会导致更多问题或者效果不佳的常见实践。它们可能在某些情况下被广泛使用&#xff0c;但实际上是无效甚至产生反效果的。 文档中并没有详细描述具…

四、Prompt工程——简单应用

Prompt工程——简单应用 一、提示工程&#xff08;Prompt Engineering&#xff09;二、Prompt基本法则三、Prompt 调优四、简单的例子文本总结文本判断文本提取文本转化——翻译文本转化——语气 更多结语 一、提示工程&#xff08;Prompt Engineering&#xff09; 提示工程也…

【华为HCIP实战课程二十五】中间到中间系统协议IS-IS配置实战续系统ID区域ID,网络工程师

上章简单讲解了ISIS基本配置,本章继续详细讲解ISIS配置及实施 IS-IS配置拓扑 1、R1进行配置IS-IS [R1]display current-configuration configuration isis isis 1 network-entity 49.0124.1111.1111.1111.00 //配置NET地址,由三部分组成,区域ID、系统ID和固定的SEL 00 i…

python道格拉斯算法的实现

废话不多说 直接开干 需要用到模块 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple math #对浮点数的数学运算函数 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple shapely #提供几何形状的操作和分析&#xff0c;如交集、并集、差集等 pip install -i …

如何保证自动化测试的可信性?

对于自动化测试的可信性&#xff0c;这是一个与自动化测试ROI&#xff08;投资回报率&#xff09;紧密关联的关键问题。自动化测试的可信性&#xff0c;不仅关乎自动化的持续性和价值&#xff0c;更重要的是它是否能够准确、真实地反映产品的质量状态。 举例来说&#xff0c;假…

鸿蒙开发-this指向+样式复用+代码调试

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;鸿蒙开发篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来鸿蒙开发篇专栏内容:鸿蒙开发-this指向样式复用代码调试 目录 一、this指向 1.原生 鸿蒙 this使用细节 -…

windows下使用nvm进行多版本nodejs管理

目录 一&#xff1a;背景 二&#xff1a;nvm的介绍 三&#xff1a;环境切换使用 一&#xff1a;背景 最近在开发node js的项目&#xff0c;其中一个项目的前端和后台使用了两个node版本&#xff0c;因此需要不同的环境配置来进行开发任务&#xff0c;刚好nvm这个插件可以实现…

vue使用高德地图实现轨迹显隐

<template><div><el-button type"primary" click"pathShowOrHide">轨迹显/隐</el-button><div id"container" /></div> </template><script> import AMapLoader from amap/amap-jsapi-loaderex…

Linux基础环境搭建(CentOS7)- 安装Scala和Spark

#Linux基础环境搭建&#xff08;CentOS7&#xff09;- 安装Scala和Spark Linux基础环境搭建&#xff08;CentOS7&#xff09;- 安装Scala和Spark 大家注意以下的环境搭建版本号&#xff0c;如果版本不匹配有可能出现问题&#xff01;&#xff08;spark不要下2.4版本的 会报错…

MySQL 日志之 binlog 格式 → 关于 MySQL 默认隔离级别的探讨

开心一刻 image 产品还没测试直接投入生产时&#xff0c;这尼玛... 背景问题 再讲 binlog 之前&#xff0c;我们先来回顾下主流关系型数据库的默认隔离级别&#xff0c;是默认隔离级别&#xff0c;不是事务有哪几种隔离级别&#xff0c;别会错题意了 1、Oracle、SQL Server 的默…

fastGpt

参考本地部署FastGPT使用在线大语言模型 1 rockylinx 1 ollama安装 在rockylinux中安装的&#xff0c;ollama由1.5G&#xff0c;还是比较大&#xff0c;所有采用在windows下下载&#xff0c;然后安装的方式&#xff0c;linux安装 tar -C /usr -xzf ollama-linux-amd64.tgz #…

让汇报结构清晰且重点突出的方法——金字塔原理

文章目录 1. 引入2. 什么是金字塔原理&#xff1f;3. 金字塔原理的 4 个要点4. 情景模拟&#xff08;项目进展汇报&#xff09;5. 小结 1. 引入 小编是一名平时埋头码代码&#xff0c;很少需要做正式的汇报&#xff0c;并且曾经一度不屑于只会做PPT和“讲故事”的人&#xff0…

小小猫棒onu替换家用光猫,薅运营商带宽羊毛,突破1000M

小小猫棒onu 一、总体步骤 1 记录原来光猫信息 主要包括SN&#xff0c;ploam密码&#xff0c;loid、loid密码、 mac、上网的vlan id等 一般gpon采用SN、ploam密码、SNploam密码三种中的一种认证方式 一般Epon采用loid&#xff08;逻辑id&#xff09;、mac、loid mac三种中…