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中的多线程
什么是多线程? 首先得知道什么是线程? 线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行.也可以把它理解为代码运行的上下文.所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务. ...
随机推荐
- java客户端与服务端交互通用处理 框架解析
一.综述 java 客户端与服务端交互过程中,采用NIO通讯是异步的,客户端基本采用同一处理范式,来进行同异步的调用处理. 处理模型有以下几个要素: 1. NIO发送消息后返回的Future 2. 每 ...
- 微信小程序自动化测试实践
由于腾讯系QQ.微信等都是基于腾讯自研X5内核,不是google原生webview(其实就是进行了二次定制).实质上也是混合应用的一种,现在很多app产品也开始流行采用X5内核作为其内嵌web浏览服务 ...
- vue项目安装vux
本文章默认基于“vue init webpack myproject”已经搭好基本的项目, 而且本文是从我有道笔记拷贝稍加修改过来的 本来我私人笔记写给自己看的所以有些地方可能描述不够清晰 需要修改的 ...
- Chapter 4 Invitations——28
"Oh, thanks, now that's all cleared up." Heavy sarcasm. “哦,真感谢,现在一切都清楚了.” 我很讽刺的说道 I realiz ...
- 性能测试-Jmeter3.1 使用技巧
一.JMeter官网 下载地址 http://jmeter.apache.org/download_jmeter.cgi Jmeter wiki https://wiki.apache.org/jme ...
- [三] java虚拟机 JVM字节码 指令集 bytecode 操作码 指令分类用法 助记符
说明,本文的目的在于从宏观逻辑上介绍清楚绝大多数的字节码指令的含义以及分类 只要认真阅读本文必然能够对字节码指令集有所了解 如果需要了解清楚每一个指令的具体详尽用法,请参阅虚拟机规范 指令简介 计算机 ...
- mpvue微信小程序多列选择器用法:实现省份城市选择
前言 微信小程序默认给我们提供了一个省市区的picker选择器,只需将mode设置为region即可 <picker mode="region" bindchange=&qu ...
- Python并发编程之消息队列补充及如何创建线程池(六)
大家好,并发编程 进入第六篇. 在第四章,讲消息通信时,我们学到了Queue消息队列的一些基本使用.昨天我在准备如何创建线程池这一章节的时候,发现对Queue消息队列的讲解有一些遗漏的知识点,而这些知 ...
- 我的 OneNote 入门心得
Microsoft OneNote 是老牌笔记类软件,在如今百花齐放的笔记类市场仍然有众多死忠粉的拥护,比如我.也试过其它笔记类软件,近年推出的 Notion 就不错,但仍然无法取代 OneNote ...
- js正则表达式 数字和小数点 非负数 保留两位小数点
验证数字非负数 小数点保留两位小数点 下面正则已验证通过 /^(?!0+(?:\.0+)?$)(?:[1-9]\d*|0)(?:\.\d{1,2})?$/