多線程如何獲取返回值


在許多時候,我們會有這樣的需求——即我們想要得到線程返回的值。但是在C++11 多線程中我們注意到,std::thread對象會忽略頂層函數的返回值。

那問題來了,我們要怎么獲得線程的返回值呢?

 

我們通過一個例子來說明如何實現這個需求。用多個線程計算(a+b)/ (x+y) 的值

 

 

有兩種方法,分別是

1. 傳統的方法:在線程間共享指針

#include<iostream>
#include<thread>
#include<mutex>
#include<atomic>
using namespace std;

void func2(int x, int y,int* ans) {
    *ans= x + y;
}

int main()
{
    //計算(a+b)/(x+y)
    //用三個線程,一個線程計算a+b,另一個線程計算x+y
    int a, b, x, y;
    a = 10, b = 8, x = 2, y = 4;

    int* sum1 = new int(0);
    int* sum2 = new int(0);
    thread t1(func2, a, b, sum1);
    t1.join();
    thread t2(func2, x, y, sum2);
    t2.join();
    
    cout << (*sum1) / (*sum2) << endl;

    delete sum1;
    delete sum2;
    
    system("pause");
    return 0;
}

 

 

 

2. C++11的方法:使用std::future和std::promise

std::future和std::promise是封裝好的兩個類模板,這兩個類需要配合使用,他們的頭文件是#include<future>

 

std::future,它表示存儲着一個未來會被初始化的變量。這個變量可以通過std::future提供的成員函數std::future::get()來得到。如果在這個變量被賦值之前就有別的線程試圖通過std::future::get()獲取這個變量,那么這個線程將會被阻塞到這個變量可以獲取為止。


std::promise同樣也是一個類模板,這個對象承諾在未來一定會初始化一個變量(這個變量也就是std::future中的變量)。

 

每一個std::promise對象都有一個與之關聯的std::future對象。當std::promise設置值的時候,這個值就會賦給std::future中的對象了。

 

#include<iostream>
#include<thread>
#include<mutex>
#include<atomic>
#include<future>   //std::future std::promise
#include<utility>   //std::ref模板傳參的時候使用

void func2(int x, int y,std::promise<int> &promiseObj) {
    promiseObj.set_value(x+y);
}

int main()
{
    //計算(a+b)/(x+y)
    //用三個線程,一個線程計算a+b,另一個線程計算x+y
    int a, b, x, y;
    a = 10, b = 8, x = 2, y = 4;

    int sum1, sum2;
    //聲明一個類
    std::promise<int> promiseObj;
    //將future和promise關聯
    std::future<int> futureObj = promiseObj.get_future();
    //模板傳參的時候使用ref,否則傳參失敗
    std::thread t1(func2, a, b, ref(promiseObj));
    t1.join();
    //獲取值
    sum1 = futureObj.get();
    std::cout << "sum1=" << sum1 << std::endl;

    //不能直接復用上面的future和promise
    std::promise<int> promiseObj2;
    std::future<int> futureObj2 = promiseObj2.get_future();

    std::thread t2(func2, x, y, ref(promiseObj2));
    t2.join();
    sum2 = futureObj2.get();
    std::cout << "sum2=" << sum2 << std::endl;

    std::cout << "sum1/sum2=" << sum1 / sum2 << std::endl;
    
    std::system("pause");
    return 0;
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM