zoukankan      html  css  js  c++  java
  • C++11之future(二)

    如果有两个线程,其中一个线程想要获取另一个线程的返回值,该怎么办?

    于是接下来要谈的package_task就是为了解决这个问题而诞生的。

    // ConsoleApplication5.cpp : 定义控制台应用程序的入口点。
    #include "stdafx.h"
    #include<random>
    #include<iostream>
    #include<vector>
    #include<thread>
    #include<algorithm>
    #include<future>
    using namespace std;
    int mythread_one()
    {
        cout << "子线程1开始执行了,id:" << this_thread::get_id() << endl;
        cout << "子线程1执行任务中...." << endl;
        this_thread::sleep_for(chrono::seconds(3));
        cout << "子线程1任务结束了" << endl;
        return 5;
    }
    
    void mythread_two(future<int> &ps)
    {
        cout << "子线程2开始执行了" << endl;
        auto x = ps.get();
        cout << "获取子线程1的值为:" << x << endl;
        cout << "子线程2任务执行结束" << endl;
    }
    int main()
    {
        //首先用pack_task包裹线程
        packaged_task<int(void)>  tp(mythread_one);
        //通过包裹的对象获取到future对象
        future<int> a = tp.get_future();
        //创建线程
    
        thread th_one(ref(tp));
        //让线程先执行起来
        th_one.join();
    
        thread th_two(mythread_two,ref(a));
        th_two.join();
    
    
        return 0;
    }

    如果有多个线程,都想要获得该值,用这个函数可以做到吗?

    下面看截取的这段代码:
    void mythread_two(future<int> &ps)
    {
        cout << "子线程2开始执行了" << endl;
        auto x = ps.get();
        cout << "获取子线程1的值为:" << x << endl;
        cout << "子线程2任务执行结束" << endl;
    }

    如果变为如下:

    void mythread_two(future<int> &ps)
    {
        cout << "子线程2开始执行了" << endl;
        auto x = ps.get();
        auto x = ps.get();
        cout << "获取子线程1的值为:" << x << endl;
        cout << "子线程2任务执行结束" << endl;
    }

    多加了一行get()语句,经过程序运行是会抛异常的。

    解释:get()函数内部实现是移动的语义,也就是说第一次调用后,里面的值已经被移动走了,如果再次调用get()的话,里面的值就为空了。

    那该如何解决多线程同时想要获取一个线程资源的方法呢?于是share_future就出现了,下面把代码进行变换:

    // ConsoleApplication5.cpp : 定义控制台应用程序的入口点。
    #include "stdafx.h"
    #include<random>
    #include<iostream>
    #include<vector>
    #include<thread>
    #include<algorithm>
    #include<future>
    using namespace std;
    int mythread_one()
    {
        cout << "子线程1开始执行了,id:" << this_thread::get_id() << endl;
        cout << "子线程1执行任务中...." << endl;
        this_thread::sleep_for(chrono::seconds(3));
        cout << "子线程1任务结束了" << endl;
        return 5;
    }
    
    void mythread_two(shared_future<int> &ps)
    {
        cout << "子线程2开始执行了" << endl;
        auto x = ps.get();
        cout << "获取子线程1的值为:" << x << endl;
        cout << "子线程2任务执行结束" << endl;
    }
    void mythread_three(shared_future<int>& ps)
    {
        cout << "子线程3开始执行了" << endl;
        auto x = ps.get();
        cout << "获取子线程1的值为:" << x << endl;
        cout << "子线程3任务执行结束" << endl;
    }
    int main()
    {
        //首先用pack_task包裹线程
        packaged_task<int(void)>  tp(mythread_one);
    
        shared_future<int> a=tp.get_future();
    
    
        thread th_one(ref(tp));
        //让线程先执行起来
        th_one.join();
    
        thread th_two(mythread_two,ref(a));
        thread th_three(mythread_three, ref(a));
        th_two.join();
        th_three.join();
    
        return 0;
    }

    如果用了share_future的话,调用get()就是值拷贝机制了,所以可以多次调用get().

     所以即使像下面这样一样ok

    void mythread_three(shared_future<int>& ps)
    {
        cout << "子线程3开始执行了" << endl;
        auto x = ps.get();
        auto x = ps.get(); 
        auto x = ps.get(); 
        cout << "获取子线程1的值为:" << x << endl;
        cout << "子线程3任务执行结束" << endl;
    }
  • 相关阅读:
    jmeter接口测试--循环获取网页中的html链接
    jmeter接口测试--文件下载
    jmeter接口测试--文件上传
    微信群发消息小工具 v1.0-可定时发送
    xmrig 源码转为vs2015项目--总结
    nginx---max_connections、meme.type、default_type
    字典 dict
    元祖 tuple
    列表list
    字符串常用方法
  • 原文地址:https://www.cnblogs.com/SunShine-gzw/p/13537126.html
Copyright © 2011-2022 走看看