关于std::thread线程传参的思考

最重要要记住的一点是:参数要拷贝到线程独立内存中,不管是普通类型、还是引用类型。

对于传递参数是引用类型,需要注意:

  • 1.当指向动态变量的指针(char *)作为实数,string const&作为形参,在传递的时候先人为增加动态变量转换string的操作。

    原因:std::thread传递参数是直接拷贝一份实参到线程独立内存的,所以假如不事先转换为string,在创建线程传递参数到std::thread构造函数后会发生隐性参数转换,但是这时类型转换操作可能会发生错误,如果发生oops,那么std::thread又只是拷贝实参的一份到自己独立内存,那么自己操作的只是一个“半成品”对象,对原来的动态变量的指针指向的字面常量没有丝毫影响。

    解决办法:在传递到std::thread构造函数前就将字面值转换为std::string对象。(std::thread t(func, std::string("hello")))

  • 2.期望传递一个引用,在新线程修改引用对象时,需要使用std::ref()修饰实参。

    原因:std::thread构造时传参传的只是实参的一份拷贝,拷贝,拷贝,不会像普通函数传参那样,函数形参是引用类型,实参是原型变量,此时调用到函数时函数会获取到对应变量的引用,修改形参引用的变量可以真正修改实参的值。std::thread传递的只是一份拷贝,传递过去一个变量值,线程形参引用的只是这个变量的拷贝的引用,对它的操作于实参没有任何影响。

    解决办法:std::thread形参是引用时,在std::thread t()创建线程的时候,需要使用std::ref()转换参数为引用,那么线程函数获取到的就是对应变量的真正引用,对它的操作就能影响真正的实参。 (void func(string& data) std::thread t(func, std::ref(data)))

  • 3.如果想对一个对象,只通过传参来被新线程使用,即把对象的使用权转移给新线程内部变量,被转移对象在主线程就被销毁,达到全局对象唯一性。

    解决办法:使用`std::move()修饰参数,可实现所有权转移。

c++11中关于`std::thread`线程传参的思考的更多相关文章

  1. c++11中关于std::thread的join的思考

    c++中关于std::thread的join的思考 std::thread是c++11新引入的线程标准库,通过其可以方便的编写与平台无关的多线程程序,虽然对比针对平台来定制化多线程库会使性能达到最大, ...

  2. std::thread函数传参拷贝次数

    c++11的thread库大大方便了开发,但是目前网络上少有深入分析的资料和使用例程.特别是在线程函数传参这一块,一般止步于使用std::ref传引用. 这次写服务器遇到个BUG,线程函数参数是智能指 ...

  3. 第24课 std::thread线程类及传参问题

    一. std::thread类 (一)thread类摘要及分析 class thread { // class for observing and managing threads public: c ...

  4. C++11 并发指南------std::thread 详解

    参考: https://github.com/forhappy/Cplusplus-Concurrency-In-Practice/blob/master/zh/chapter3-Thread/Int ...

  5. C++11并发之std::thread<转>

    最近技术上没什么大的收获,也是悲催的路过~ 搞一点新东西压压惊吧! C++11并发之std::thread 知识链接: C++11 并发之std::mutex C++11 并发之std::atomic ...

  6. std::thread线程库详解(2)

    目录 目录 简介 最基本的锁 std::mutex 使用 方法和属性 递归锁 std::recursive_mutex 共享锁 std::shared_mutex (C++17) 带超时的锁 总结 简 ...

  7. C++11中的std::bind

    C++11中的std::bind 最近在看看cocos2dx的源代码,发现了cocos2dx 3.0相对于2.0改动了很多,最大的改变就是大量的使用了C++11的特性,比如auto等.其中有一个关于回 ...

  8. C#基础知识回顾--线程传参

    C#基础知识回顾--线程传参 在不传递参数情况下,一般大家都使用ThreadStart代理来连接执行函数,ThreadStart委托接收的函数不能有参数, 也不能有返回值.如果希望传递参数给执行函数, ...

  9. java 线程传参 方式

    第一类:主动向线程传参   public class ThreadTest extends Thread { public ThreadTest() { } /** * 第一种通过构造方法来传递参数 ...

随机推荐

  1. Burpsuite模块—-Intruder模块详解

    一.简介 Burp Intruder是一个强大的工具,用于自动对Web应用程序自定义的攻击,Burp Intruder 是高度可配置的,并被用来在广范围内进行自动化攻击.你可以使用 Burp Intr ...

  2. linux中memset的正确用法

    linux中memset的正确用法 [起因]希望对各种类型的数组进行初始化,避免野值 [函数头文件] 提示:在linux中可以在terminal中输入 "man memset"进行 ...

  3. Awake & Start

    [Awake & Start] MonoBehaviour.Awake() Awake is used to initialize any variables or game state be ...

  4. SpringMVC+springSecurity+flexPaper 配置--类似百度文库在线预览

    背景:现在项目需要做一个类似百度文库的在线预览功能,在网上找了下很多人推荐使用FlexPaper,所以今天尝试学习了FlexPaper顺便集成到现有的框架中 由于网上目前的说的都不是很详细,所以现在记 ...

  5. 414. Third Maximum Number数组中第三大的数字

    [抄题]: Given a non-empty array of integers, return the third maximum number in this array. If it does ...

  6. jQuery--修改表单数据并提交

    目的: ​点击'编辑',弹出对话框,修改数据. 主要知识点: prevAll(),获取同级别本元素前面的所有元素. 代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...

  7. anacondas 下 安装xgboost & keras

    mac : 安装anaconda, cd到anaconda 目录下 pip install xgboost 测试: 在当前的¥ python , 进入python 环境 import xgboost ...

  8. Luogu 4781 【模板】拉格朗日插值

    模板题. 拉格朗日插值的精髓在于这个公式 $$f(x) = \sum_{i = 1}^{n}y_i\prod _{j \neq i}\frac{x - x_i}{x_j - x_i}$$ 其中$(x_ ...

  9. Smarty3——foreach

    foreach and  foreachelse篇 foreach用于遍历数组,可以是非关联数组,与section相比要简单些,在smarty3中可以接受没有名称的属性,也可以使用smarty2有名称 ...

  10. 循环删除DataTable.Row中的多行问题

    在C#中,如果要删除DataTable中的某一行,大约有以下几种办法: 1,使用DataTable.Rows.Remove(DataRow),或者DataTable.Rows.RemoveAt(ind ...