线程的理解及基本操作

目录

一、线程的理解

(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的起始地址)。

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

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

相关文章

常见网安面试题

《Java代码审计》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484219&idx1&sn73564e316a4c9794019f15dd6b3ba9f6&chksmc0e47a67f793f371e9f6a4fbc06e7929cb1480b7320fae34c32563307df3a28aca49d1a4addd&scene21#wechat_redirect 《网安面试指南…

初探Servlet

文章目录 1. Servlet概述1.1 定义1.2 作用 2. 主要知识点2.1 生命周期2.2 请求处理2.3 Servlet配置 3. 案例演示3.1 创建Web应用项目3.2 修改项目工件名3.3 重新部署Web项目3.4 创建WelcomeServlet3.5 编写doGet方法代码3.6 编写doPost方法代码3.7 访问WelcomeServlet 4. 小结 …

【modbus协议】Modbus-TCP消息帧格式

文章目录 协议描述Modbus Application Header 结构示例与其他部分的关系作用总结 协议描述 在ModbusTCP/IP协议中,串行链路中的主/从设备分别演变为客户端/服务器端设备。即客户端相当于主站设备,服务器端相当于从站设备。基于TCP/IP网络的传输特性。Modbus协议在TCP/IP上的实…

VsCode | 修改内置字体为JetBrains Mono NL

文章目录 一、下载JetBrains Mono NL字体二、VsCode进行字体的设置 一、下载JetBrains Mono NL字体 字体下载 下载完成以后解压找到JetBrainsMono-2.304\fonts\ttf文件夹下,全选鼠标右键点安装即可。 注意:一定要全部安装,否则字体样式可…

QT仿QQ聊天项目,第二节,美化登录界面

一,控件起名和设置整体样式 目录 一,控件起名和设置整体样式 二,设置局部控件样式 三,设置gif动态背景 四,设置账号密码框样式 五,头像图片设置 给控件起的名字: 关闭按钮: btn_close 缩小…

轻松部署自己的AI聊天助手LocalGPT并实现无公网IP远程交互

文章目录 前言环境准备1. localGPT部署2. 启动和使用3. 安装cpolar 内网穿透4. 创建公网地址5. 公网地址访问6. 固定公网地址 前言 本文主要介绍如何本地部署LocalGPT并实现远程访问,由于localGPT只能通过本地局域网IP地址端口号的形式访问,实现远程访问…

N-154基于springboot酒店预订管理系统

开发工具:IDEA 服务器:Tomcat9.0, jdk1.8 项目构建:maven 数据库:mysql5.7 前端技术:AdminLTEBootstrapLayUIHTMLjQuery 服务端技术:springbootmybatis-plusthymeleaf 本项目分前台和后台…

Banana Pi BPI-R3路由器开发板运行 OrayOS物联网系统

近日,Banana PI开发板宣布与贝锐达成战略合作,贝锐OrayOS现已成功适配Banana PI的BPI-R3型号,并计划进一步扩展硬件支持,包括目前Banana PI热销的BPI-R4、BPI-R3 Mini等更多型号。这一合作为用户提供了更广泛的开发板选择&#xf…

范式转移:从协程、回调到异步

本文使用 CC BY-NC-ND 4.0 许可。 原文:英文版 | 中文版 协程、回调和异步每一个单独拎出来讲都不难,但它们之间的关系却非常烧脑,迄今为止我还没见过哪篇文章能讲清楚的,所以在这里我尝试用最简单的思路讲解清楚:如…

Pytorch学习--神经网络--非线性激活

一、用法 torch.nn.ReLU 图像处理中的应用:在图像处理任务中,ReLU 激活函数能够增强特征提取的能力,使网络更好地捕捉图像的细节和边缘。这是因为 ReLU 对大部分负数响应为零,能在一定程度上减少网络计算量,并对特征…

Objective-C 音频爬虫:实时接收数据的 didReceiveData_ 方法

在互联网技术领域,数据的获取和处理是至关重要的。尤其是对于音频内容的获取,实时性和效率是衡量一个爬虫性能的重要指标。本文将深入探讨在Objective-C中实现音频爬虫时,如何高效地使用didReceiveData:方法来实时接收数据,并通过…

企业自建邮件系统选U-Mail ,功能强大、安全稳定

在现代企业运营中,电子邮件扮演着至关重要的角色,随着企业规模的增长和业务的多样化,传统的租用第三方企业邮箱服务逐渐显现出其局限性。例如,存储空间受限、数据安全风险、缺乏灵活的管理和备份功能,以及无法与其他企…

C++在实际项目中的应用第二节:C++与区块链

第五章:C在实际项目中的应用 第二课:C与区块链 区块链技术因其去中心化、不可篡改和透明性而受到广泛关注。在这门课程中,我们将深入探讨区块链的基本原理、智能合约的开发以及实际应用的案例分析,重点使用 C 作为实现语言&…

雷池社区版中升级雷池遇到问题

关于升级后兼容问题 版本差距过大会可能会发生升级后数据不兼容导致服务器无法起来 跨多个版本(超过1个大版本号)升级做好数据备份,遇到升级失败可尝试重新安装解决 升级提示目录不对 在错误的目录下执行(比如 safeline 的子目…

TCP/IP Attack Lab

网络拓扑: Task 1: SYN Flooding Attack 收到攻击之前,在Victim主机查看网络连接的状态: 在攻击之前使用User1主机(10.9.0.6)访问Victim(10.9.0.5)主机的 Telnet服务: Task 1.1: Launching the Attack Using Python 在Atacker上建立文件attack-1.py…

Jvm中的堆和栈

JVM中的堆和栈分别存放不同的数据类型和内容。 ‌栈(Stack)‌: 存储基本数据类型(如int, char, boolean等)和对象的引用。存储局部变量、方法调用、程序运行状态、方法返回值等。每个线程都有一个独立的线程栈&#…

我为什么投身于青少年AI编程?——打造生态圈(三)

第五部分 青少年AI编程生态圈 一、生态圈 主要涵盖家庭、社区/中小学、高校高职、主管部门。 1、家庭 我们与社区/中小学一道打造让家长满意的模式。 教得好: 费用少: 家门口: 2、社区/中小学 社区党群服务中心和中小学都有大面积科普…

Ubuntu18.04安装vscode1.94.2失败安装vscode1.84.2

系统环境:Ubuntu18.04.6 LTS 自己先去vscode官网下载好最新版本的vscode1.94.2(不下也行,反正最新版也用不了,哈哈) 网址:Visual Studio Code - Code Editing. RedefinedVisual Studio Code is a code ed…

.NET 8 中的 Mini WebApi

介绍 .NET 8 中的极简 API 隆重登场,重新定义了我们构建 Web 服务的方式。如果您想知道极简 API 的工作原理以及它们如何简化您的开发流程,让我们通过一些引人入胜的示例来深入了解一下。 .NET 极简主义的诞生 想想我们曾经不得不为一个简单的 Web 服务…

鸿蒙开发融云demo发送图片消息

鸿蒙开发融云demo发送图片消息 融云鸿蒙版是不带UI的,得自己一步步搭建。 这次讲如何发送图片消息,选择图片,显示图片消息。 还是有点难度的,好好看,好好学。 一、思路: 选择图片用:photoVie…