编程语言
首页 > 编程语言> > C++11笔记-多线程-async()和Future

C++11笔记-多线程-async()和Future

作者:互联网

多线程高级接口:async和Future

C++11提供的多线程开发接口中分为高级接口和低级接口;
高级接口就是C++标准库中由std::async()和class std::future<>提供的高级接口;

async()和Future的第一个用例

功能需求

需求,计算两个操作数的总和,并在控制台上输出操作数表示的ASCII码;
设定两个操作数的输出字符函数分别func1和func2函数;
串行编程模型的做法是:
func1()+func2();
执行的次序为:先执行func1()函数,再执行func2()函数;总耗时为func1函数耗时+func2函数耗时+计算总和时间;或者两个函数执行顺序相反,取决于不同编译器;
并行编程模型的做法是:
对func1函数分配一个单独线程执行;
同时执行func2函数;
在计算func1和func2的和时,等待func1函数执行完成;
总耗时为:func1或者func2两者中耗时最长的时间+计算总和时间

代码实现

#include <iostream>
#include <thread>
#include <future>
#include <chrono>
#include <random>
#include <exception>

using namespace std;

int doSomething(char c)
{
    default_random_engine dre(c);
    uniform_int_distribution<int> id(10, 1000);
	// 在控制台上打印字符,增加延时,防止函数很快执行完成;
    for (size_t i = 0; i < 10; i++)
    {
        this_thread::sleep_for(chrono::milliseconds(id(dre)));
        cout.put(c).flush();
    }
    return c;
}

int func1()
{
    return doSomething('.');
}

int func2()
{
    return doSomething('+');
}
int main()
{
	cout << "starting func1() in background" << " and func2() in foreground:" << endl;
	future<int> result1(async(func1));
    int result2 = func2();
    int result = result1.get() + result2;
    cout << "\n result of func1()+func2(): " << result << endl;
    system("pause");
}

运行结果如下:
在这里插入图片描述

代码剖析

关于随机生成数和增加的sleep_for这部分内容不详细讲解,毕竟多线程async和future才是我们学习的目标;
与之前说过的并行编程模型的步骤相同;
函数执行的流程为:

  1. 使用async()尝试启动func1()于后台,并将结果赋值给某个future对象;在这里,async()函数尝试将其所获得的函数立即启动于一个分离线程内。大白话就是func1()放到了一个线程并开始执行,与main函数同时执行,不会造成main函数的停滞。
    关于为啥要将async()函数的结果赋值给future,原因有二:
  1. 在前台main函数启动func2函数,是常规的同步执行顺序,程序需要在func2函数执行完成后在执行下一条语句;
  2. 计算func1和func2的总和;
    int result = result1.get() + result2;
    

需要获取到func1函数的结果和func2函数的结果,func2的结果比较简单,result2就是该函数的返回值;func1由于分离到另外一个线程,就需要通过future对象来获取返回值,使用future的get函数获取func1函数的执行结果;
我们对future调用get时,会出现三种情况:

总结

一般使用async和future怎么实现一个多线程的功能;
常规的流程是:

1.引用#include <future>;
2.传递某些可并行执行的函数,交给std::async()作为一个可调用对象(callable object)。
3.将执行结果赋值给一个future<ReturnType> object。
4.当你需要那个被启动函数的执行结果,或当你想确保该函数结束,就对future<> object调用get()。

注意:这里没有考虑到线程之间对数据的竞态情况;
注意:如果没有调用get()就不保证func1()函数会被调用;
注意:如果std::async()启动的函数是一个无返回值的函数,则会产生一个future<void>对象,是future<>的一个偏特化版,这种情况下get()返回“无物”;
注意:传给async()的东西可以是任何类型的callable object:可以是函数、成员函数、函数对象(function object)或lambda表达式;

引用

1.《C++标准库》第二版

标签:11,func2,func1,函数,get,future,async,多线程,Future
来源: https://blog.csdn.net/liushao1031177/article/details/116855224