Linux--线程的分离、线程库的地址关系的理解、线程的简单封装(二)

线程系列:
线程的认识:讲解线程的概念和线程的基本控制

线程的分离

线程分离是指将一个线程从主线程中分离出来,使其能够独立运行。当一个线程被设置为分离状态时,它结束时系统会自动回收其资源,而不需要其他线程使用pthread_join()函数来等待其结束并手动回收资源。

设置线程分离的方法
使用pthread_detach()函数:在线程创建后,可以通过调用pthread_detach()函数来将线程设置为分离状态。这个函数是非阻塞式的,即调用后不会阻塞当前线程的执行。
在创建线程时设置分离属性:另一种方法是在创建线程时,通过pthread_create()函数的第二个参数(线程属性)来设置线程为分离状态。这种方法在创建线程时即指定了其分离属性,效率相对较高。

void* threadrun(void* args)
{string name = static_cast<const char *>(args);while(true){sleep(1);cout<<"this is new thread:"<<name<<endl;}
}
int main()
{pthread_t tid;pthread_create(&tid, nullptr, threadrun, (void *)"thread 1");cout << "main thread wait block" << std::endl;pthread_join(tid, nullptr);cout << "main thread wait return"<<endl;
}

在这里插入图片描述

使用分离函数后:
在这里插入图片描述

再加个有限时间的循环看看:
在这里插入图片描述
对线程分离理解虽然新线程与主线程已经分离了,但它们仍然是同一进程中的执行流,如果程序使用时出现异常时(新线程或者主线程),那么两个程序都会终止;或者说主线程结束了,实际上就代表进程结束了;所以线程的分离仍然是在进程中进行的,受进程的影响

何时使用:当线程完成任务后不需要与其结果交付时;当线程在后台运行且不需要与主线程进行同步进行时;

注意:分离线程无法重新连接!而可连接线程可以分离,当只有在尚未开始运行之前

理解线程库的地址关系

在这里插入图片描述

在这里插入图片描述

线程栈

线程栈是与线程紧密相关的内存区域,用于存储线程的局部变量、函数调用的返回地址以及线程的执行上下文等信息每个线程都有自己独立的栈空间,这保证了线程之间的数据是隔离的,从而避免数据竞争和线程安全问题。

#include<iostream>
using namespace std;
#include<pthread.h>
#include<unistd.h>
void *threadrun1(void *args)
{  std::string name = static_cast<const char *>(args);int g_val=100;while(true){sleep(1);printf("%s, g_val: %lu, &g_val: %p\n", name.c_str(), g_val--, &g_val);}return nullptr;
}void *threadrun2(void *args)
{std::string name = static_cast<const char *>(args);int g_val=100;while(true){printf("%s, g_val: %lu, &g_val: %p\n", name.c_str(), g_val--, &g_val);sleep(1);}return nullptr;
}int main()
{pthread_t tid1;pthread_t tid2;pthread_create(&tid1, nullptr, threadrun1, (void *)"thread 1");pthread_create(&tid2, nullptr, threadrun2, (void *)"thread 2");pthread_join(tid1, nullptr);pthread_join(tid2, nullptr);
}

通过两个新线程都创建一个局部变量(变量名相同),比较它们的地址;
在这里插入图片描述
可以看到g_val在各自线程是不一样的,地址也是不同的;

线程局部存储(TLS)

线程局部存储(TLS)是一种机制,允许每个线程拥有自己的私有数据副本,即使不同线程执行相同的代码,TLS变量与常规全局变量是不同的,因为每个线程堆TLS变量的访问都是独立的。

一般适用于:

  • 线程特定数据:当某些数据只对特定线程有意义,并且需要在线程内保持状态时,可以使用线程局部存储。
  • 全局状态隔离:通过将全局状态分离为每个线程的私有副本,可以提高并发性能,避免线程间的数据竞争。
  • 线程上下文保存:线程局部存储也可用于保存当前执行线程的上下文信息,如用户身份验证信息、数据库连接等。

注意:

线程局部存储变量通常只能用于具有静态或线程存储期的变量,不能用于自动或动态分配的变量。使用线程局部存储时需要谨慎管理内存,避免内存泄漏或无效访问等问题。

线程的封装

线程的封装通常指的是将线程的创建、执行、同步、资源管理等逻辑封装到一个类或对象中,以便更好地组织代码,提高代码的可读性和可维护性

封装线程可以隐藏线程的复杂性,使得其他部分的代码可以更加简洁地与线程进行交互。

下面看具体代码:

Thread.hpp:对线程的封装

#ifndef __THREAD_HPP__
#define __THREAD_HPP__#include<iostream>
#include<string>
#include<pthread.h>
#include<functional>
#include<unistd.h>using namespace std;namespace ThreadMdule
{//通过模板类可调用一切任何对象template<typename T>using func_t = std::function<void(T&)>;template<typename T>class Thread{public:void Excute(){_func(_data);}Thread(func_t<T> func, T data, const std::string &name="none-name"): _func(func), _data(data), _threadname(name), _stop(true){}static void* threadroutine(void* args){Thread<T>* self=static_cast<Thread<T>*>(args);self->Excute();return nullptr;}bool start(){int n=pthread_create(&_tid,nullptr,threadroutine,this);if(!n){_stop = false;return true;}else{return false;}}void Detach(){if(!_stop){pthread_detach(_tid);}}void Join(){if(!_stop){pthread_join(_tid,nullptr);}}string name(){return _threadname;}void Stop(){_stop = true;}~Thread() {}private:pthread_t _tid;std::string _threadname;T _data;  func_t<T> _func;bool _stop;};
}#endif

线程类中包括了:线程名,数据,调用函数指针等;
通过start()函数来创建新线程:用到了函数threadroutinue,在函数中将函数成员_func(也就是具体函数的指针)使用了起来,就表示新线程的创建使用;

主函数的调用:

void print(int &cnt)
{while (cnt){std::cout << "hello I am myself thread, cnt: " << cnt-- << std::endl;sleep(1);}
}const int num=3;
int main()
{vector<Thread<int>> threads;//创建新线程for(int i=0;i<num;i++){string name="thread"+to_string(i + 1);threads.emplace_back(print,3,name);}//启动进程for(auto& thread:threads){thread.start();}//等待进程结束for(auto& thread:threads){thread.Join();cout<<"wait thread done,thread is: "<<thread.name()<<endl;}return 0;
}

在这里插入图片描述
这样就是对线程的简单封装;

通过封装线程,我们可以更好地控制线程的创建、执行和销毁过程,同时使得代码更加清晰和易于维护。

此外,封装还可以帮助我们添加额外的功能,比如线程池的集成、异常处理、线程同步等。

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

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

相关文章

ArcGIS空间数据处理、空间分析与制图;PLUS模型和InVEST模型的原理,参量提取与模型运行及结果分析;土地利用时空变化以及对生态系统服务的影响分析

工业革命以来&#xff0c;社会生产力迅速提高&#xff0c;人类活动频繁&#xff0c;此外人口与日俱增对土地的需求与改造更加强烈&#xff0c;人-地关系日益紧张。此外&#xff0c;土地资源的不合理开发利用更是造成了水土流失、植被退化、水资源短缺、区域气候变化、生物多样性…

如何在XDMA中查看LTSSM状态机

简介 经常会遇到PCIe不能识别的问题&#xff0c;到底怎么去定位。本文以XDMA 为例&#xff0c;一方面复习下LTSSM状态机&#xff0c;一方面描述下如何通过FPGA的XDMA查看这个状态机 技术名词 LTSSM是一种常用于PCI Express&#xff08;PCIe&#xff09;接口的状态机&#xf…

「前端+鸿蒙」核心技术HTML5+CSS3(四)

1、CSS三大特性 CSS的三大特性指的是层叠(Cascading)、继承(Inheritance)和样式(Style)。 层叠(Cascading):当多个样式规则应用于同一个元素时,CSS规定了样式的优先级,以确定哪个样式将被应用。层叠顺序由选择器的特异性、来源(如内联样式、内部样式表、外部样式表…

北京大学第一医院与智源研究院共同发布基于可信执行环境的AI医学影像挑战赛

肾动脉狭窄是导致继发性高血压及肾功能不全的常见原因&#xff0c;而目前针对肾动脉狭窄功能学的评估尚处于探索阶段。数据保护和可信计算环境是目前人工智能技术应用于临床研究的一大瓶颈。北京大学第一医院与北京智源人工智能研究院心脏AI 联合研究中心特发布基于可信执行环境…

Ubuntu22.04之解决:Flameshot无法截图问题(二百三十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Ant design vue的表格双击编辑功能(即双击开始编辑并自动获得焦点,失去焦点时完成编辑)

本文基于Ant Design Vue官方网站的表格&#xff08;可编辑单元格&#xff09;&#xff08;表格 Table - Ant Design Vue (antdv.com))中的样板代码获得双击编辑且获得焦点、失去焦点时完成编辑的功能。 要点&#xff1a; &#xff08;1&#xff09;双击时候实现编辑&#xff…

如何使用Cloudways搭建WordPress网站(附最新Cloudways优惠码)

如今&#xff0c;搭建网站已经变得非常简单&#xff0c;这主要得益于开源的CMS建站系统的兴起。即使是不懂编程的人也能轻松搭建自己的网站&#xff0c;这些CMS系统提供了丰富的主题模板和插件&#xff0c;使用户可以通过简单的拖放和配置操作来建立自己的网站。 WordPress是目…

子网划分案例

4.2子网划分 “有类编址”的地址划分过于死板&#xff0c;划分的颗粒度太大&#xff0c;会有大量的主机号不能被充分利用&#xff0c;从而造成了大量的IP地址资源浪费。因此可以利用子网划分来减少地址浪费&#xff0c;即VLSM (Variable Length Subnet Mask)&#xff0c;可变长…

Vue3学习- setup 使用 useRoute函数返回为 undefined,语法糖与非语法糖的错误、正确的写法情况

代码情况 import { ref,computed,watch,reactive } from vue import { RouterView,RouterLink,useRoute,useRouter } from vue-router import HelloWorld from ./components/HelloWorld.vue function toggleRoute(){const temprou useRoute()console.log(temprou); }正确 im…

国内前十款专业外盘期货交易app软件排名盘点(综合版)

随着社会经济的不断发展&#xff0c;现在投资者倾向于投资各种项目以获取超额收益。在选择外盘期货交易app软件时&#xff0c;有几个关键的因素需要考虑。首先是软件的可靠度和安全度&#xff0c;因为交易涉及到实际资金。因此&#xff0c;需要选择具备专业资质、经验丰富、充分…

mybatis问题汇总

Mapped Statements collection does not contain value for mapper.xml中namespace存在问题 使用 ${}实现关键字&#xff08;表名、列名&#xff09;的可变 #{} 和 ${} 的区别

Android下HWC以及drm_hwcomposer普法(上)

Android下HWC以及drm_hwcomposer普法(上) 引言 按摩得全套&#xff0c;错了&#xff0c;做事情得全套&#xff0c;普法分析也是如此。drm_hwcomposer如果对Android图形栈有一定研究的童鞋们应该知道它是Android提供的一个的图形后端合成处理HAL模块的实现。但是在分析这个之前…

汽车悬架分为哪几类

汽车悬架分为哪几类 1)汽车的悬架系统可根据结构分为两种:独立悬架和非独立悬架,独立悬架根据构造又可以分为CDC运动悬架(CDC电磁悬架系统)和空气悬架; 2)当前比较火热的空气悬架,是独立悬架的一种; 3)前轮主要使用麦弗逊式独立悬架 和 双叉臂悬架,后轮主要使用多…

实景三维简介

实景三维简介 一、实景三维定义 实景三维&#xff08;3D real scene&#xff09;&#xff0c;是一个专业术语&#xff0c;对一定范围内人类生产、生活和生态空间进行真实、立体、时序化反映和表达的数字空间。 对一定范围内人类生产、生活和生态空间进行真实、立体、时序化反…

倒角距离【Chamfer Distance】

倒角距离&#xff08;chamfer distance&#xff09;是用于评估两组点之间的相似度的度量。给定两个点集 A 和 B&#xff0c;倒角距离定义为 A 中每个点到 B 中最近邻点的距离之和&#xff0c;加上 B 中每个点到 A 中最近邻点的距离之和。它用于各种应用&#xff0c;包括计算机视…

nginx 反向代理配置详解

Nginx 反向代理是一种常用的部署策略&#xff0c;用于将客户端请求转发到内部网络中的一个或多个服务器&#xff0c;这些服务器直接处理请求并返回响应给Nginx&#xff0c;再由Nginx转交给客户端。这种设置可以提高网站的可用性和安全性&#xff0c;同时也能实现负载均衡、缓存…

数据分析——分群思维、RFM实现用户分群

分群思维 按照某个指标&#xff08;可以是用户生命周期、活跃度、付费&#xff09;来划分用户 分群好处&#xff1a; 1.是用户精细化运营的基础&#xff0c;也就是说只有分群了才可以针对每一个群进行运营策略 2.体现用户的差异性&#xff0c;比较不同层级的差异更能发现问题 …

每期一个小窍门 k8s版本的 Prometheus + grafana + alertmanager 三件套部署监控落地

首先部署prometheus 首先是pvc apiVersion: v1 kind: PersistentVolumeClaim metadata:name: prometheus-data-pvcnamespace: monitor spec:accessModes:- ReadWriteManystorageClassName: "data-nfs-storage"resources:requests:storage: 10Gi然后接着 cluster-ro…

CSS+Canvas绘制最美星空(一闪一闪亮晶晶效果+流星划过)

1.效果 2.代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><style>body,html {margin: 0;padding: 0;ov…

商业应用中的AI模型选择:开源还是闭源?

评价一个AI模型“好不好”、“有没有发展”&#xff0c;往往绕不开“开源”和“闭源”这两条不同的发展路径。这两种路径各有优劣&#xff0c;从数据隐私、商业应用和社区参与三个方面来看&#xff0c;我们可以更全面地理解它们的差异和影响。 方向一&#xff1a;数据隐私 开…