要将参数传递给线程的可关联对象或函数,只需将参数传递给std::thread构造函数。

默认情况下,所有的参数都将复制到新线程的内部存储中。

看一个例子:

给线程传递单个参数

#include <iostream>
#include <string>
#include <thread>void threadCallback(int x, std::string str) {std::cout << "Passed Number = " << x << std::endl;std::cout << "Passed String = " << str << std::endl;
}
int main() {int x = 10;std::string str = "Sample String";std::thread threadObj(threadCallback, x, str);threadObj.join();return 0;
}

怎样给线程传递函数
不要将本地堆栈变量的地址传递给线程的回调函数,因为线程1中的局部变量可能会超出范围,但线程2仍然尝试通过它的地址访问它。
在这种情况下,访问无效地址可能会导致不可预测的行为。
例如:

#include <iostream>
#include <thread>void newThreadCallback(int* p)  {std::cout << "Inside Thread :  "" : p = " << *p << std::endl;std::chrono::milliseconds dura(1000);std::this_thread::sleep_for(dura);*p = 19;
}void startNewThread()  {int i = 10;std::cout << "Inside Main Thread :  "" : i = " << i << std::endl;std::thread t(newThreadCallback, &i);t.detach();std::cout << "Inside Main Thread :  "" : i = " << i << std::endl;
}int main()  {startNewThread();std::chrono::milliseconds dura(2000);std::this_thread::sleep_for(dura);return 0;
}  

同样的,在将指针传递给位于heap上的线程时,要小心,因为某些线程可能在新线程尝试访问它之前删除该内存。
在这种情况下,访问无效地址可能会导致不可预测的行为。

例如:

#include <iostream>
#include <thread>void newThreadCallback(int* p) {std::cout << "Inside Thread :  "" : p = " << *p << std::endl;std::chrono::milliseconds dura(1000);std::this_thread::sleep_for(dura);*p = 19;
}void startNewThread() {int* p = new int();*p = 10;std::cout << "Inside Main Thread :  "" : *p = " << *p << std::endl;std::thread t(newThreadCallback, p);t.detach();delete p;p = NULL;
}int main() {startNewThread();std::chrono::milliseconds dura(2000);std::this_thread::sleep_for(dura);return 0;
}  

给线程传递引用

由于参数被复制到新的线程堆栈,所以,如果想通过常用的方式传递引用,如:

#include <iostream>
#include <thread>void threadCallback(int const& x) {int& y = const_cast<int&>(x);y++;std::cout << "Inside Thread x = " << x << std::endl;
}int main() {int x = 9;std::cout << "In Main Thread : Before Thread Start x = " << x << std::endl;std::thread threadObj(threadCallback, x);threadObj.join();std::cout << "In Main Thread : After Thread Joins x = " << x << std::endl;return 0;
} 

输出为:

In Main Thread : Before Thread Start x = 9 
Inside Thread x = 10 
In Main Thread : After Thread Joins x = 9

即使threadCallback接受参数作为引用,但是并没有改变main中x的值,在线程引用外它是不可见的。
这是因为线程函数threadCallback中的x是引用复制在新线程的堆栈中的临时值。

如何修改:
使用 std::ref

#include <iostream>
#include <thread>void threadCallback(int const& x) {int& y = const_cast<int&>(x);y++;std::cout << "Inside Thread x = " << x << std::endl;
}int main() {int x = 9;std::cout << "In Main Thread : Before Thread Start x = " << x << std::endl;std::thread threadObj(threadCallback, std::ref(x));threadObj.join();std::cout << "In Main Thread : After Thread Joins x = " << x << std::endl;return 0;
}

输出:

In Main Thread : Before Thread Start x = 9

Inside Thread x = 10

In Main Thread : After Thread Joins x = 10

指定一个类的成员函数的指针作为线程函数。将指针传递给成员函数作为回调函数,并将指针指向对象作为第二个参数

本文转自:c++11多线程编程(三):仔细地将参数传递给线程_小麒麟的成长之路-CSDN博客

#include <iostream>
#include <thread>class DummyClass {public:DummyClass() { }DummyClass(const DummyClass& obj) { }void sampleMemberfunction(int x) {std::cout << "Inside sampleMemberfunction " << x << std::endl;}
};int main() {DummyClass dummyObj;int x = 10;std::thread threadObj(&DummyClass::sampleMemberfunction, &dummyObj, x);threadObj.join();return 0;
}  

c++11仔细地将参数传递给线程std::thread相关推荐

  1. c++ 线程 std::thread

    1.创建一个线程 创建线程比较简单,使用std的thread实例化一个线程对象就创建完成了,示例: #include<iostream> #include<thread>  / ...

  2. Linux下基于C++11的socket网络编程(线程版本)

    第一:关于C++11的线程操作 哈哈,百度这个比较直接,可以很清楚的告诉你. 第二:声明 不再追溯,可以先看看(基础版本)(进程版本)(select函数版本)(epoll版本)再看这个,谢谢. 工具类 ...

  3. 【多线程】C++11进行多线程开发 (std::thread)

    文章目录 创建线程 std::thread 类 使用join() 使用 detach() 警惕作用域 线程不能复制 给线程传参 传递指针 传递引用 以类成员函数为线程函数 以容器存放线程对象 互斥量 ...

  4. C++11学习笔记-----线程库std::thread

    在以前,要想在C++程序中使用线程,需要调用操作系统提供的线程库,比如linux下的<pthread.h>.但毕竟是底层的C函数库,没有什么抽象封装可言,仅仅透露着一种简单,暴力美 C++ ...

  5. java:编写10个线程,第一个线程从1加到10,第二个线程从11加到20……第十个线程从91加到100, 最后再,10个线程结果相加

    在生活中,人体可以同时进行各项生命活动.例如,人体可以同时进行呼吸.血液循环等等- 当我们在编写程序时,这些行为我们可以抽象为并发,而将并发完成的每一件事称为线程. 线程创建的两种传统方式 方式一:继 ...

  6. C++11多线程第三篇:线程传参详解,detach()大坑,成员函数做线程参数

    文章目录 3.1 传递临时对象作为线程参数 3.1.1 要避免的陷阱(解释1) 3.1.2 要避免的陷阱(解释2) 3.1.3 总结 3.2 临时对象作为线程参数进一步详解 3.2.1 线程id概念 ...

  7. WCF后续之旅(11): 关于并发、回调的线程关联性(Thread Affinity)

    对于一般的多线程操作,比如异步地进行基于文件系统的IO操作:异步地调用Web Service:或者是异步地进行数据库访问等等,是和具体的线程无关的.也就是说,对于这些操作,任意创建一个新的线程来执行都 ...

  8. 编写10个线程,第一个线程从1加到10,第二个线程从11加到20…第十个线程从91加到100, 最后再把10个线程结果相加。

    package net.paoyun.day18.thread.zuoye; /**  * 编写10个线程,第一个线程从1加到10,第二个线程从11加到20-第十个线程从91加到100, 最后再把10 ...

  9. JMeter参数传递,线程内传递和线程组间传递

    JMeter参数传递,线程内传递和线程组间传递 线程内参数传递 线程间参数传递 线程内参数传递 回归测试,登录接口和其他接口在一个线程组中. 1.登陆后json提取器获取token 2.将token存 ...

最新文章

  1. Facebook加入AI芯片大战,挖走Google芯片产品开发负责人
  2. R语言将dataframe数据从宽表变为长表实战(melt函数、pivot_longer函数、gather函数)
  3. python能在工程上干嘛-python能干什么?
  4. Node.js webpack-dev-server配置命令的两种方式
  5. PowerPC中断系统简介(一)
  6. 11款有用的Web开发在线工具
  7. eclipse 对齐行号在括号中显示和字体调整
  8. 分布式锁双重防死锁演进
  9. 阿里云mysql创建多个用户_阿里云MySQL创建指定用户访问指定表
  10. 百度地图根据经纬度获取地址
  11. 7805输入电流有要求吗_防雷!防护电路在PCB走线方面的要求(某500强企业内部资料~)...
  12. ubuntu下搭建erlang编程环境
  13. ZeroClipboard实现复制
  14. Linq的Distinct太不给力了
  15. 常用数学符号大全、关系代数符号
  16. 实时Linux之PREEMPT_RT篇
  17. 用浏览器访问防火墙提示建立连接失败的有点总结
  18. 永远不要和沙雕一样的人去争论,争论最后你会发现你也是一个沙雕
  19. MPAndroidChart 饼状图 文字重叠问题完美解决
  20. Java IDE - Selenium 包下载

热门文章

  1. c 类别构造函数需要包含所有成员吗_C++默认成员函数解析
  2. c语言中虚函数和纯虚函数,虚函数和纯虚函数的区别是什么?
  3. python异常处理的作用_python之路——异常处理
  4. 产品型号 计算机硬件,主流CPU产品型号后缀名详解_CPUCPU评测-中关村在线
  5. c语言位操作大小写转换,C语言实现大小写转换的三种方法
  6. the job was canceled什么意思_什么第三人称单数形式?怎么用?
  7. Day03 javascript详解
  8. protobuf java基础
  9. 应用jacob组件造成的内存溢出解决方案(java.lang.OutOfMemoryError: Java heap space)
  10. 好书推荐之《活着》 隐私策略(Privacy policy)