c++并发编程/多线程 thread 库

系列文章目录


文章目录

  • 系列文章目录
  • -进程
  • -前言
      • base类
      • 线程执行函数
      • 结果分析
      • 小结,行为总结
  • -c++11线程对象创建后既不join()也不detach()的后果
  • -
  • 附注代码


-进程

进程是运行着的程序

进程内存空间分配:略

如果主进程结束而子进程未结束,则Linux内核会将该子进程的父进程ID改为1(init进程),

-前言

void funcname(const A& v);

std::thread(funcname, value); // 即使函数的形参是引用类型也会发生拷贝构造,
除非:
void funcname(A& v);
std::thread(funcname, std::ref(value)); // 这样value对象就是主线程中的对象

base类

#include <iostream>
#include <thread>class Base
{
public:int num = 1;  // 类内初始化Base() { std::cout << "默认构造函数Base()运行 "<< " this: " << this << " id= "<< std::this_thread::get_id() << std::endl;}Base(const Base& b){std::cout << "拷贝构造函数Base(&)"<< " this: " << this << " id= "<< std::this_thread::get_id() << std::endl;}~Base(){std::cout << "析构函数~Base()"<< " this: " << this << " id= "<< std::this_thread::get_id() << std::endl;}void operator()(int num){std::cout << "运算符重载,子线程执行: "<< " this: " << this << " id= "<< std::this_thread::get_id() << std::endl;}void thdjob(int n);
};

线程执行函数

  1. 普通函数
    void thdjob(int n)
    {std::cout << "子线程执行:" << std::this_thread::get_id() << std::endl;
    }
    
  2. 类的成员函数
    void Base::thdjob(int n){std::cout << "子线程执行:" << std::this_thread::get_id() << std::endl;}
    

结果分析

int main()
{Base b;// 在第一个参数为普通函数的情况下,引用?// 当第一个参数为类的成员函数时,则子线程和主线程用的不是同一个对象// 若为引用或地址则为同一个对象std::thread thd(&Base::thdjob, b, 4);
}

小结,行为总结

  • std::thread中,即使线程函数的形参是引用类型也会进行对象拷贝
  • std::thread(…)中假定所有实参都为右值
    void thdjob(const Base& b); // 必须是const引用,并且会发生
    
  • 无对象拷贝的方式:
    1. 引用
       void thdjob(Base& b);// 子线程中的对象b与主线程中的是同一个,自然无对象拷贝// 需要确保子线程在使用b时,主线程不会将其销毁std::thread th(thdjob, std::ref(b));  // std::ref将b变为引用类型
      
    2. 指针
       void thdjob(Base* b);// 用地址传递自然都是同一个对象std::thread th(thdjob, &b);
      
  • 发生对象拷贝
    1.  2次拷贝,主线程子线程各一次
      void thdjob(Base b);
      std::thread th(thdjob, b);
      
      发生两次对象拷贝,第一次发生在主线程,将b对象拷贝到th,第二次发生在子线程,将th中的右值对象拷贝到形参
      默认构造函数Base()运行  this: 0x7ffcd8b7f014 id= 139770366710720
      ----------
      拷贝构造函数Base(&) this: 0x558e2431d2c8 id= 139770366710720
      拷贝构造函数Base(&) this: 0x7f1ed29fed74 id= 139770359445056
      this: 0x7f1ed29fed74子线程执行:139770359445056
      
    2.  1次拷贝
      // 子线程发生一次对象拷贝
      void thdjob(Base b);
      // std::ref  主线程无拷贝
      std::thread th(thdjob, std::ref(b));
      
      默认构造函数Base()运行  this: 0x7ffd5c67123c id= 139786634453952
      ----------
      拷贝构造函数Base(&) this: 0x7f229c3fed74 id= 139786627053120
      this: 0x7f229c3fed74子线程执行:139786627053120
      

      推荐的方式
      // 子线程无拷贝
      void thdjob(const Base& b);
      // 主线程进行1次对象拷贝
      std::thread th(thdjob, b);
      
      默认构造函数Base()运行  this: 0x7ffd26fb3764 id= 140183106712512
      ----------
      拷贝构造函数Base(&) this: 0x563e24eee2c8 id= 140183106712512
      this: 0x563e24eee2c8子线程执行:140183099930176
      
      解析:主线程创建b的拷贝,即使主线程结束也是安全的;子线程引用b的拷贝,当子线程结束时负责析构该对象。

-c++11线程对象创建后既不join()也不detach()的后果

c++11中,创建对象(std::thread)后有两种状态:

joinablenonjoinable

线程对象通过默认构造函数构造后状态为nonjoinable; 线程对象通过有参构造函数创建后状态为join able。joinable状态的线程对象被调用join()或detach()会变为nonjoinable状态。

线程对象析构

// thread类中的析构函数定义:
~thread()
{if(nonjoinable){std::terminate();}
}

线程对象析构时,会判断线程的状态。如果线程处于join able状态时,会调用terminate()函数直接令程序退出。

也就是说,创建一个可运行(创建时传入线程函数)线程对象后,必须对该对象进行处理,要么调用join()要么调用detach(),否则线程对象析构时程序将直接退出。

-


附注代码

推荐的方式

void testfn(const Base & b)
{std::cout << "this = " << &b << " tid = " << std::this_thread::get_id()<< std::endl;usleep(10000000);std::cout << b.num << std::endl;
}void subth()
{Base B;std::cout << "subth Base B this =  " << &B << " tid = " << std::this_thread::get_id() << std::endl;std::thread th(testfn, B);th.detach();
}int main()
{std::cout << "main tid: " << std::this_thread::get_id() << std::endl;std::thread th(subth);th.detach();std::cout << "main sleep" << std::endl;while(1);
}
main tid: 140303695139776
main sleep
默认构造函数Base()运行  this: 0x7f9aff7fed6c id= 140303688267328
subth Base B this =  0x7f9aff7fed6c tid = 140303688267328
拷贝构造函数Base(&) this: 0x7f9af8000b78 id= 140303688267328
析构函数~Base() this: 0x7f9aff7fed6c id= 140303688267328
this = 0x7f9af8000b78 tid = 140303679874624
1
析构函数~Base() this: 0x7f9af8000b78 id= 140303679874624

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

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

相关文章

YOLO目标检测——无人机航拍行人检测数据集下载分享【含对应voc、coc和yolo三种格式标签】

实际项目应用&#xff1a;智能交通管理、城市安防监控、公共安全救援等领域数据集说明&#xff1a;无人机航拍行人检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富标签说明&#xff1a;使用lableimg标注软件标注&#xff0c;标注框质量高&#xff0c;…

流量主接入广告:实现盈利与用户体验的平衡

在互联网时代&#xff0c;网站和应用程序的盈利模式之一就是通过接入广告来获取流量变现。作为关键一环的流量主&#xff0c;如何巧妙地接入广告&#xff0c;既保证了盈利&#xff0c;又不损害用户体验&#xff0c;成为了一个备受关注的话题。 admaoyan猫眼聚合 广告形式的选择…

python运算符重载之构造函数和迭代器

1 python运算符重载之构造函数和迭代器 python运算符重载是在类方法中拦截内置操作-当类的实例使用内置操作时&#xff0c;pytho自动调用对应方法&#xff0c;并且返回操作结果。 NO#描述1拦截运算运算符重载拦截内置操作&#xff0c;比如打印、函数调用、点号运算、表达式运…

ubuntu20编译安装pkg-config

从下载到安装的步骤如下: wget https://pkg-config.freedesktop.org/releases/pkg-config-0.29.tar.gztar -zxvf pkg-config-0.29.tar.gzcd pkg-config-0.29/./configure --with-internal-glibsudo makesudo make checksudo make install make过程中可能会遇到的问题&#x…

2023年通信安全员ABC证证模拟考试题库及通信安全员ABC证理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年通信安全员ABC证证模拟考试题库及通信安全员ABC证理论考试试题是由安全生产模拟考试一点通提供&#xff0c;通信安全员ABC证证模拟考试题库是根据通信安全员ABC证最新版教材&#xff0c;通信安全员ABC证大纲整理…

DBS note3:B+ Trees

目录 1、介绍 2、B树特征 3、插入 4、删除 5、存储记录 1&#xff09;方法1&#xff1a;按值存储 2&#xff09;方法2&#xff1a;按引用存储 3&#xff09;方法3&#xff1a;按引用列表存储 6、聚类&#xff08;Clustering&#xff09; 1&#xff09;非聚类&#xff…

调整Windows键盘上只能看到拼音而无法看到实际的文本以及关闭输入法悬浮窗方法

一、输入法设置 如果您在键盘上只能看到拼音而无法看到实际的文本&#xff0c;这可能是因为您的输入法设置为中文拼音输入法或其他仅显示拼音的输入法。 要解决这个问题&#xff0c;您可以尝试以下方法&#xff1a; 1. 切换输入法&#xff1a;按下 Shift Alt 组合键或 Wind…

python -opencv 边缘检测

python -opencv 边缘检测 边缘检测步骤: 第一步&#xff1a;读取图像为灰度图 第二步&#xff1a;进行二值化处理 第三步&#xff1a;使用cv2.findContours对二值化图像提取轮廓 第三步&#xff1a;将轮廓绘制到图中 代码如下&#xff1a; from ctypes.wintypes import SIZ…

聊一聊go的单元测试

文章目录 概要一、测试框架1.1、testing1.2、stretchr/testify1.3、smartystreets/goconvey1.4、cweill/gotests 二、打桩和mock2.1、打桩2.2、mock2.2.1、mockgen 三、基准测试和模糊测试3.1、基准测试3.2、模糊测试 四、总结4.1、小结4.2、其他4.3、参考资料 概要 软件测试是…

前端入门(二)Vue2到Vue3

文章目录 Vue简介Vue的特点Hello, Vue Vue基本语法模板语法数据绑定&#xff08;v-bind、v-model&#xff09;el与data的两种写法 数据代理实现原理Object.defineProperty()数据代理 事件处理&#xff08;v-on:click / click&#xff09;事件修饰符键盘事件&#xff08;略&…

万户OA upload任意文件上传漏洞复现

0x01 产品简介 万户OA ezoffice是万户网络协同办公产品多年来一直将主要精力致力于中高端市场的一款OA协同办公软件产品&#xff0c;统一的基础管理平台&#xff0c;实现用户数据统一管理、权限统一分配、身份统一认证。统一规划门户网站群和协同办公平台&#xff0c;将外网信息…

信息系统项目管理师-采购管理论文提纲

快速导航 1.信息系统项目管理师-项目整合管理 2.信息系统项目管理师-项目范围管理 3.信息系统项目管理师-项目进度管理 4.信息系统项目管理师-项目成本管理 5.信息系统项目管理师-项目质量管理 6.信息系统项目管理师-项目资源管理 7.信息系统项目管理师-项目沟通管理 8.信息系…

配置 `PostgreSQL` 与 `Keepalived` 以实现高可用性

配置 PostgreSQL 与 Keepalived 以实现高可用性通常包括以下步骤&#xff1a; PostgreSQL 配置 安装 PostgreSQL&#xff1a;在两台服务器上安装相同版本的 PostgreSQL。 sudo yum install postgresql-server postgresql-contrib初始化数据库&#xff1a;在两台服务器上初始化…

OSG文字-显示汉字 (1)

OSG文字 适当的文字信息对于显示场景信息是非常重要的。在 OSG中&#xff0c;osgText 提供了向场景中添加文字的强大功能&#xff0c;由于有第三方插件 FreeType 的支持&#xff0c;它完全支持TrueType字体。 读者可能对 FreeType和TrueType还不太了解&#xff0c;下面进行具体…

在windows Server安装Let‘s Encrypt的SSL证书

1、到官网&#xff08;https://certbot.eff.org/instructions?wswebproduct&oswindows&#xff09;下载 certbot客户端。 2、安装客户端&#xff08;全部默认安装即可&#xff09; 3、暂停IIS中的网站 开始菜单中找到并运行“Certbot”&#xff0c;输入指令&#xff1a; …

新一代车载以太网传输技术研讨会(AEM)顺利圆满举行

时间定格在2023年11月17日&#xff0c;新一代车载以太网传输技术研讨会在东莞国际会展中心举行。来自相关的的企业几百家。当然&#xff0c;深圳维信仪器作为主办方&#xff08;AEM线束测试仪中国区总平台&#xff09;举优质的线束测试设备&#xff0c;不论是手持线束测试&…

Vue3 源码解读系列(十二)——指令 directive

directive 定义&#xff1a;本质就是一个 JavaScript 对象&#xff0c;对象上挂着一些钩子函数。 实现&#xff1a;在元素的生命周期中注入代码。 指令注册 注册原理&#xff1a;把指令的定义保存到相应的地方&#xff0c;未来使用的时候可以从保存的地方拿到。 全局注册与…

Swagger-----knife4j框架

简介 使得前后端分离开发更加方便&#xff0c;有利于团队协作 接口的文档在线自动生成&#xff0c;降低后端开发人员编写接口文档的负担 功能测试 Spring已经将Swagger纳入自身的标准&#xff0c;建立了Spring-swagger项目&#xff0c;现在叫Springfox。通过在项目中引入Spri…

mysql innodb buffer pool缓冲池命中率和命中了哪些表?—— 筑梦之路

环境说明 mysql 5.7及以上 公式 # InnoDB缓冲区缓存的命中率计算公式100 * (1 - (innodb_buffer_pool_reads/innodb_buffer_pool_read_requests ))注意: 对于具有大型缓冲池的系统&#xff0c;既要关注该比率&#xff0c;也要关注OS页面读写速率的变化可以更好地跟踪差异。s…

【BUG库】 记录自己学习工作中遇到的程序BUG

BUG库 CGoGO语言环境配置相关go mod algorithm环境相关vscode -- 保存vscode -- 注释 在这篇博客中 我会记录自己在学习和工作中遇到的一系列bug C Go GO语言环境配置相关 go mod go: go.mod file not found in current directory or any parent directory; see ‘go help …