c++11仔细地将参数传递给线程std::thread
要将参数传递给线程的可关联对象或函数,只需将参数传递给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相关推荐
- c++ 线程 std::thread
1.创建一个线程 创建线程比较简单,使用std的thread实例化一个线程对象就创建完成了,示例: #include<iostream> #include<thread> / ...
- Linux下基于C++11的socket网络编程(线程版本)
第一:关于C++11的线程操作 哈哈,百度这个比较直接,可以很清楚的告诉你. 第二:声明 不再追溯,可以先看看(基础版本)(进程版本)(select函数版本)(epoll版本)再看这个,谢谢. 工具类 ...
- 【多线程】C++11进行多线程开发 (std::thread)
文章目录 创建线程 std::thread 类 使用join() 使用 detach() 警惕作用域 线程不能复制 给线程传参 传递指针 传递引用 以类成员函数为线程函数 以容器存放线程对象 互斥量 ...
- C++11学习笔记-----线程库std::thread
在以前,要想在C++程序中使用线程,需要调用操作系统提供的线程库,比如linux下的<pthread.h>.但毕竟是底层的C函数库,没有什么抽象封装可言,仅仅透露着一种简单,暴力美 C++ ...
- java:编写10个线程,第一个线程从1加到10,第二个线程从11加到20……第十个线程从91加到100, 最后再,10个线程结果相加
在生活中,人体可以同时进行各项生命活动.例如,人体可以同时进行呼吸.血液循环等等- 当我们在编写程序时,这些行为我们可以抽象为并发,而将并发完成的每一件事称为线程. 线程创建的两种传统方式 方式一:继 ...
- C++11多线程第三篇:线程传参详解,detach()大坑,成员函数做线程参数
文章目录 3.1 传递临时对象作为线程参数 3.1.1 要避免的陷阱(解释1) 3.1.2 要避免的陷阱(解释2) 3.1.3 总结 3.2 临时对象作为线程参数进一步详解 3.2.1 线程id概念 ...
- WCF后续之旅(11): 关于并发、回调的线程关联性(Thread Affinity)
对于一般的多线程操作,比如异步地进行基于文件系统的IO操作:异步地调用Web Service:或者是异步地进行数据库访问等等,是和具体的线程无关的.也就是说,对于这些操作,任意创建一个新的线程来执行都 ...
- 编写10个线程,第一个线程从1加到10,第二个线程从11加到20…第十个线程从91加到100, 最后再把10个线程结果相加。
package net.paoyun.day18.thread.zuoye; /** * 编写10个线程,第一个线程从1加到10,第二个线程从11加到20-第十个线程从91加到100, 最后再把10 ...
- JMeter参数传递,线程内传递和线程组间传递
JMeter参数传递,线程内传递和线程组间传递 线程内参数传递 线程间参数传递 线程内参数传递 回归测试,登录接口和其他接口在一个线程组中. 1.登陆后json提取器获取token 2.将token存 ...
最新文章
- Facebook加入AI芯片大战,挖走Google芯片产品开发负责人
- R语言将dataframe数据从宽表变为长表实战(melt函数、pivot_longer函数、gather函数)
- python能在工程上干嘛-python能干什么?
- Node.js webpack-dev-server配置命令的两种方式
- PowerPC中断系统简介(一)
- 11款有用的Web开发在线工具
- eclipse 对齐行号在括号中显示和字体调整
- 分布式锁双重防死锁演进
- 阿里云mysql创建多个用户_阿里云MySQL创建指定用户访问指定表
- 百度地图根据经纬度获取地址
- 7805输入电流有要求吗_防雷!防护电路在PCB走线方面的要求(某500强企业内部资料~)...
- ubuntu下搭建erlang编程环境
- ZeroClipboard实现复制
- Linq的Distinct太不给力了
- 常用数学符号大全、关系代数符号
- 实时Linux之PREEMPT_RT篇
- 用浏览器访问防火墙提示建立连接失败的有点总结
- 永远不要和沙雕一样的人去争论,争论最后你会发现你也是一个沙雕
- MPAndroidChart 饼状图 文字重叠问题完美解决
- Java IDE - Selenium 包下载
热门文章
- c 类别构造函数需要包含所有成员吗_C++默认成员函数解析
- c语言中虚函数和纯虚函数,虚函数和纯虚函数的区别是什么?
- python异常处理的作用_python之路——异常处理
- 产品型号 计算机硬件,主流CPU产品型号后缀名详解_CPUCPU评测-中关村在线
- c语言位操作大小写转换,C语言实现大小写转换的三种方法
- the job was canceled什么意思_什么第三人称单数形式?怎么用?
- Day03 javascript详解
- protobuf java基础
- 应用jacob组件造成的内存溢出解决方案(java.lang.OutOfMemoryError: Java heap space)
- 好书推荐之《活着》 隐私策略(Privacy policy)