博客
关于我
(C++11/14/17学习笔记):future其他成员函数、shared_future、atomic
阅读量:342 次
发布时间:2019-03-04

本文共 4088 字,大约阅读时间需要 13 分钟。

std::future与shared_future:多线程编程中的数据传递与共享

std::future的成员函数与get()函数

在C++多线程编程中,std::future是一个用于表示尚未完成的定时操作的对象。它提供了一系列成员函数,用于管理和等待这些操作的完成。最核心的成员函数之一是get(),用于获取操作的结果。然而,get()函数具有移动语义,这意味着一旦调用get(),future对象将失去其结果,无法再次调用get(),否则会抛出异常。

std::future_status枚举值与future对象.wait_for

std::future_status是一个枚举类型,用于描述等待操作时的状态。可能的取值包括:

  • ready:表示操作已经完成,可以立即获取结果。
  • timeout:表示等待超时,操作未完成。
  • deferred:表示操作延迟执行,尚未完成。

以下是一个使用std::future和wait_for的示例:

#include 
#include
#include
#include
#include
#include
using namespace std;int mythread() { cout << "mythread start" << "ThreadId = " << this_thread::get_id() << endl; chrono::milliseconds dura(5000); this_thread::sleep_for(dura); cout << "mythread end" << "ThreadId = " << this_thread::get_id() << endl; return 100;}int main() { cout << "MianThreadID = " << this_thread::get_id() << endl; future
ret = async(mythread); future_status status = ret.wait_for(chrono::seconds(1)); if (future_status::timeout == status) { cout << "超时,线程没有执行完" << endl; } // 主线程执行 cout << "主线程结束" << endl; return 0;}

std::shared_future:get()函数复制数据

与std::future不同,std::shared_future允许通过get()获取数据多次。然而,get()仍然具有移动语义,这意味着调用get()后,shared_future对象将失去其值。为了避免重复获取数据,可以将shared_future对象共享。

以下是一个使用std::shared_future的示例:

#include 
#include
#include
#include
#include
#include
#include
using namespace std;void mythread(std::promise
& tmp, int clc) { cout << "mythread start" << "ThreadId = " << this_thread::get_id() << endl; clc++; clc *= 233; chrono::milliseconds dura(5000); this_thread::sleep_for(dura); tmp.set_value(ret); cout << "mythread end" << "ThreadId = " << this_thread::get_id() << endl; return;}void mythread2(std::shared_future
& tmp) { cout << "mythread2 start" << "ThreadId = " << this_thread::get_id() << endl; auto val = tmp.get(); cout << "mythread2 val = " << val << endl; cout << "mythread2 end" << "ThreadId = " << this_thread::get_id() << endl; return;}int main() { cout << "MianThreadID = " << this_thread::get_id() << endl; promise
var_pro; thread objThread(mythread, ref(var_pro), 10); objThread.join(); future
ret = var_pro.get_future(); bool ifcanget = ret.valid(); cout << "ret.valid() get前的值 " << ifcanget << endl; shared_future
ret_s(std::move(ret)); ifcanget = ret.valid(); cout << "ret.valid() get后的值 " << ifcanget << endl; auto mythreadResualt = ret_s.get(); mythreadResualt = ret_s.get(); cout << "ret_s.valid() 连续get两次后的值 " << ret_s.valid() << endl; thread objThread2(mythread2, ref(ret_s)); objThread2.join(); // 主线程执行 cout << "主线程结束" << endl; return 0;}

std::atomic:原子操作的概念

在多线程编程中,原子操作是一种可以在多线程环境下安全执行的操作。它不需要显式的互斥机制(如锁),可以直接对共享变量进行操作。std::atomic是一个类模板,用于封装类型值,支持原子操作。

原子操作的概念

原子操作是一种不可分割的操作,执行时要么完全完成,要么完全未完成。它通常用于以下场景:

  • 计数:统计发送或接收的数据包数量。
  • 统计:累加操作(如计数器)。

原子操作的实现

以下是一个使用std::atomic的示例:

#include 
#include
#include
#include
#include
using namespace std;std::atomic
my_count{0};void my_thread() { for (int i = 0; i < 1000000; i++) { my_count++; } return;}int main() { thread threadObj1(my_thread); thread threadObj2(my_thread); threadObj1.join(); threadObj2.join(); cout << "两个线程执行完毕,最终 my_count的值是" << my_count << endl; return 0;}

通过互斥量实现原子操作

如果不使用std::atomic,可以通过互斥量(如std::mutex)实现原子操作:

#include 
#include
#include
#include
#include
using namespace std;std::mutex my_mutex;void my_thread() { for (int i = 0; i < 1000000; i++) { my_mutex.lock(); my_count++; my_mutex.unlock(); } return;}int main() { thread threadObj1(my_thread); thread threadObj2(my_thread); threadObj1.join(); threadObj2.join(); cout << "两个线程执行完毕,最终 my_count的值是" << my_count << endl; return 0;}

原子操作的效率优势

使用互斥量实现的原子操作效率较低,约6秒完成。而使用std::atomic的原子操作效率更高,执行时间大幅缩短。

总结

在C++多线程编程中,std::future和std::shared_future用于管理和等待定时操作的结果,而std::atomic则提供了一种高效的原子操作机制。通过合理选择和正确使用这些工具,可以在多线程环境中实现数据的安全共享与传递。

转载地址:http://wdyr.baihongyu.com/

你可能感兴趣的文章
Windows系统Git安装教程
查看>>
hibernate和mybatis的区别
查看>>
你为什么从大公司离职,去一家创业公司?
查看>>
MyBatis学习总结(三)——优化MyBatis配置文件中的配置
查看>>
JavaWeb学习总结(十三)——使用Session防止表单重复提交
查看>>
JavaScript学习总结(十一)——Object类详解
查看>>
Java中Map的用法详解
查看>>
Java注解全面总结
查看>>
base64编码字符串和图片的互转
查看>>
汉字转为拼音
查看>>
Target runtime Apache Tomcat v7.0 is not defined.错误解决方法
查看>>
Python+Opencv识别视频统计人数
查看>>
PCL点云交流群
查看>>
python 记录下Python开发环境的安装配置
查看>>
大佬龟叔写的一个无聊程序
查看>>
linux 下安装kolla报错 提示Cannot uninstall requests
查看>>
Linux MySQL的socket文件存在位置更改
查看>>
Linux RPM和yum命令的使用技巧
查看>>
Python 使jupyter notebook 从指定浏览器启动 以及编程中途更换浏览器
查看>>
写博客常用的字体颜色(待续)
查看>>