c/c++ 多线程 参数传递
多线程 参数传递
1,值传递,拷贝一份新的给新的线程。线程1中有个int变量a,在线程1中启动线程2,参数是a的值,这时就会拷贝a,线程1和线程2不共享a。
2,引用传递,不拷贝一份新的给新的线程。线程1中有个int变量a,在线程1中启动线程2,参数是a的引用,这时就不会拷贝a,线程1和线程2共享a。※传递参数时,必须明确指出使用std::ref函数,不写std::ref,编译不过。
3,指针传递,浅拷贝原来的指针给新的线程。线程1中有个指向int变量a的指针,在线程1中启动线程2,参数是a的地址,这时就不会拷贝a,只是浅拷贝指向a的指针,线程1和线程2共享a。
4,unique_ptr作为参数传递,必须使用move函数
5,函数的指针作为参数传递
引用传递,指针传递的注意事项:因为线程2里使用的是线程1的变量a,所以如果线程1比线程2提前结束了,结束的同时就会释放变量a的内存空间,可是这时线程2还没结束,再去访问线程1中的变量a的话,就会发生意想不到的错误!!!
2,引用传递,例子:
一共3个线程,main函数是一个线程,在main函数里启动了线程2(f1函数),在线程2(f1函数)里启动了线程3(f2函数)。
#include <iostream>
#include <thread>
#include <string>
#include <unistd.h>
using namespace std;
void f2(int& i){
cout << "f2:" << i << endl;
}
void f1(int& i){
cout << "f1:" << i << endl;
int j = 11;
thread t(f2, ref(j));//-------------->②
t.detach();
}
int main(){
int i = 10;
thread t(f1, ref(i));
t.detach();//-------------->①
pthread_exit(NULL);
}
执行结果:
f1:10
f2:0
执行结果分析:
- 打印出【f1:10】的原因可能是,①处分离线程后,main函数所在的线程还没有结束,所以i还没有被释放掉,所以能打印出10;还有可能是main函数所在的线程虽然已经结束了,但是巧合的是值还是10。
- 打印出【f2:0】的原因是,②处分离线程后,线程f1已经结束了,所以函数f1里的j已经被释放了,这时线程f2再访问j的时候就是0了。
3,指针传递,例子:
一共3个线程,main函数是一个线程,在main函数里启动了线程2(f1函数),在线程2(f1函数)里启动了线程3(f2函数)。
#include <iostream>
#include <thread>
#include <string>
#include <unistd.h>
using namespace std;
void f2(int* i){
cout << "f2:" << *i << endl;
}
void f1(int& i){
cout << "f1:" << i << endl;
int j = 11;
thread t(f2, &j);
t.detach();//-------------->②
}
int main(){
int i = 10;
thread t(f1, ref(i));
t.detach();//-------------->①
pthread_exit(NULL);
}
执行结果:
f1:10
f2:0
执行结果分析:
- 打印出【f1:10】的原因可能是,①处分离线程后,main函数所在的线程还没有结束,所以i还没有被释放掉,所以能打印出10;还有可能是main函数所在的线程虽然已经结束了,但是巧合的是值还是10。
- 打印出【f2:0】的原因是,②处分离线程后,线程f1已经结束了,所以函数f1里的j已经被释放了,这时线程f2再访问j的时候就是0了。
4,unique_ptr作为参数传递,必须使用move函数
#include <iostream>
#include <thread>
#include <string>
#include <unistd.h>
using namespace std;
void f1(unique_ptr<int> upt){
cout << *upt << endl;
}
int main(){
unique_ptr<int> upt(new int(10));
//必须使用move函数,否则编译不过
thread t(f1, move(upt));
t.detach();
pthread_exit(NULL);
}
5,函数的指针作为参数传递
#include <iostream>
#include <thread>
#include <string>
#include <unistd.h>
using namespace std;
class Test{
public:
void func(int& i){
cout << i << endl;
}
};
int main(){
Test da;
int i = 10;
//&Test::func为对象的方法的指针,&da为对象的指针,ref(i)是方法func的参数
thread t(&Test::func, &da, ref(i));
t.detach();
pthread_exit(NULL);
}
c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854
c/c++ 多线程 参数传递的更多相关文章
- C# 多线程参数传递
之前使用多线程的时候,基本没有遇到过参数传递的情况,最近,接连遇到需要进行参数传递的多线程的使用.每次都要重新上网查一下,太麻烦了.为了方便以后的使用,就把经常参阅的网上资料记录下来. 原文地址如下: ...
- 20160208.CCPP体系详解(0018天)
程序片段(01):main.c 内容概要:PointWithOutInit #include <stdio.h> #include <stdlib.h> //01.野指针详解: ...
- QT多线程信号和槽参数传递
写了一个这样的信号 void caculateReady( QList<QString> adds, QList<double> hotV, QList<double&g ...
- Win32 API 多线程编程——一个简单实例(含消息参数传递)
Win32 API进行程序设计具有很多优点:应用程序执行代码小,运行效率高,但是他要求程序员编写的代码较多,且需要管理所有系统提供给程序的资源,要求程序员对Windows系统内核有一定的了解,会占用程 ...
- C++并发与多线程学习笔记--参数传递详解
传递临时对象 陷阱 总结 临时对象作为线程参数 线程id的概念 临时对象构造时的抓捕 成员函数指针做线程函数 传递临时对象作为线程参数 创建的工作线程不止一个,线程根据编号来确定工作内容.每个线程都需 ...
- C#多线程之线程池篇3
在上一篇C#多线程之线程池篇2中,我们主要学习了线程池和并行度以及如何实现取消选项的相关知识.在这一篇中,我们主要学习如何使用等待句柄和超时.使用计时器和使用BackgroundWorker组件的相关 ...
- C#多线程之线程同步篇2
在上一篇C#多线程之线程同步篇1中,我们主要学习了执行基本的原子操作.使用Mutex构造以及SemaphoreSlim构造,在这一篇中我们主要学习如何使用AutoResetEvent构造.Manual ...
- C++ 11 多线程--线程管理
说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...
- java中的多线程
什么是多线程? 首先得知道什么是线程? 线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行.也可以把它理解为代码运行的上下文.所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务. ...
随机推荐
- CoCos2dx开发:tile地图绘制和Tiled工具的基本使用
1.新建地图: 在Tiled工具里新建文件: 设置地图的地图大小和地图块大小: 新建好的空文件如下: 2.绘制图块: 在Aseprite中建立相应大小(注意:划分的图块为32*32,因此图片大小最好与 ...
- Data - Tools
数据工具汇总 史上最全的大数据分析和制作工具 全球100款大数据工具汇总 SQL 数据分析常用语句 01 - NumPy HomePage:http://www.numpy.org/ NumPy(数值 ...
- mongodb高级聚合查询
在工作中会经常遇到一些mongodb的聚合操作,特此总结下.mongo存储的可以是复杂类型,比如数组.对象等mysql不善于处理的文档型结构,并且聚合的操作也比mysql复杂很多. 注:本文基于 mo ...
- IntelliJ IDEA下SVN的配置及使用说明
1 下载及安装SVN客户端. 到官网下载小乌龟SVN客户端,官网地址:https://tortoisesvn.net/downloads.html,根据操作系统情况选择适合版本.比如64为操作系统,如 ...
- Python内置函数(54)——reversed
英文文档: reversed(seq) Return a reverse iterator. seq must be an object which has a __reversed__() meth ...
- java代码之美(4)---guava之Immutable(不可变)集合
Immutable(不可变)集合 一.概述 guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开.Collections是jdk提供的一个工具类 ...
- Spring AOP实现统一日志输出
目的: 统一日志输出格式 思路: 1.针对不同的调用场景定义不同的注解,目前想的是接口层和服务层. 2.我设想的接口层和服务层的区别在于: (1)接口层可以打印客户端IP,而服务层不需要 (2)接口层 ...
- 带着新人学springboot的应用13(springboot+热部署)
spring cloud我想做成一个系列,所以spring cloud+eureka后面会慢慢说到的,有兴趣的小伙伴可以关注后续! 这一节就简单说说springboot的热部署了(我一直想不通为什么叫 ...
- web缓存策略之HTTP缓存大全
一. web缓存总分类 数据库数据缓存 Web应用,特别是SNS类型的应用,往往关系比较复杂,数据库表繁多,如果频繁进行数据库查询,很容易导致数据库不堪重荷.为了提供查询的性能,会将查询后的数据放到内 ...
- 重写(override)和重载(overload)的区别
override(重写): 是进行基类中函数的重写,是面向对象的概念 重载(overload):是方法的名称相同,参数或参数类型不同,进行多次重载以适应不同的需要.overload 是面向对象的概念.