C++:来自 std::thread 的简单返回值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7686939/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:21:13  来源:igfitidea点击:

C++: Simple return value from std::thread?

c++multithreading

提问by shoosh

With win32 threads I have the straight forward GetExitCodeThread()that gives me the value which the thread function returned. I'm looking for something similar for std::thread(or boost threads)
As I understand this can be done with futures but how exactly?

使用 win32 线程,我可以直接GetExitCodeThread()给出线程函数返回的值。我正在为std::thread(或提升线程)寻找类似的东西
据我所知,这可以用期货来完成,但究竟如何?

回答by Alex B

See this video tutorialon C++11 futures.

请参阅有关 C++11 期货的视频教程

Explicitly with threads and futures:

明确地使用线程和期货:

#include <thread>
#include <future>

void func(std::promise<int> && p) {
    p.set_value(1);
}

std::promise<int> p;
auto f = p.get_future();
std::thread t(&func, std::move(p));
t.join();
int i = f.get();

Or with std::async(higher-level wrapper for threads and futures):

或者使用std::async(线程和期货的高级包装器):

#include <thread>
#include <future>
int func() { return 1; }
std::future<int> ret = std::async(&func);
int i = ret.get();

I can't comment whether it works on allplatforms (it seems to work on Linux, but doesn't build for me on Mac OSX with GCC 4.6.1).

我无法评论它是否适用于所有平台(它似乎适用于 Linux,但不适用于带有 GCC 4.6.1 的 Mac OSX)。

回答by sehe

I'd say:

我会说:

#include <thread>
#include <future>

int simplefunc(std::string a)
{ 
    return a.size();
}

int main()
{
      auto future = std::async(simplefunc, "hello world");
      int simple = future.get();

      return simple;
}

Note that async even propagates any exceptions thrown from the thread function

请注意,异步甚至会传播从线程函数抛出的任何异常

回答by Daksh

Using C++11 threads, one can't get the return value as thread exit which used to be the case with pthread_exit(...)

使用 C++11 线程,无法在线程退出时获得返回值,这曾经是这种情况 pthread_exit(...)

You need to use C++11 Future<>to get the return value. Future is created using templated argument where the template takes the return value (built in of User Defined types)..

您需要使用 C++11Future<>来获取返回值。Future 是使用模板化参数创建的,其中模板采用返回值(内置于用户定义类型)。

You can fetch the value in another thread using future<..>::get(..)function.

您可以使用future<..>::get(..)函数在另一个线程中获取值。

one benefit of using future<..>is that you can check the validity of return value i.e if it's already taken, you avoid calling get()accidentally by checking the validity using future<..>::isValid(...)function.

使用的一个好处future<..>是你可以检查返回值的有效性,即如果它已经被占用,你可以get()通过使用future<..>::isValid(...)函数检查有效性来避免意外调用。

Here is how you'll write the code.

以下是您将如何编写代码。

#include <iostream>
#include <future>
using namespace std;
auto retFn() {
    return 100;
}
int main() {
    future<int> fp = async(launch::async, retFn);
    if(fp.valid())
       cout<<"Return value from async thread is => "<<fp.get()<<endl;
    return 0;
}

it should also be noted that we can get the future run on the same thread by using launch::deferredoption as

还应该注意的是,我们可以通过使用launch::deferred选项让未来在同一线程上运行

 future<int> fp = async(launch::deferred, retFn);

回答by Martin G

I think a reference variable reads much more intuitively.

我认为参考变量读起来更直观。

int x = 0;
std::thread theThread(threadFunction, std::ref(x));
theThread.join();
std::cout << x << std::endl;

回答by Zhang

Here is a more specific example.

这是一个更具体的例子。

A function simulates download with a callback parameter to show progress and to cancel the download.

函数使用回调参数模拟下载以显示进度并取消下载。

namespace __HeavyWork
{
    int SimulateDownload(std::function<int(int)> dlCallBack)
    {
        for (size_t i = 0; i < 100; i++)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));

            if (dlCallBack(i) == -1)
            {
                return i;
            }
        }

        return 100;
    }
}

We want to get the download status,

我们想获取下载状态,

#include <thread>
#include <future>

    void test()
    {
        auto simulateCancellation = []()->bool {
            static bool b = true;
            if (b)
            {
                srand((unsigned int)time(NULL));
                b = false;
            }
            return (rand() % 7) == 0;
        };

        auto funDLCallback = [&](int i)->int {
            if (simulateCancellation())
            {
                return -1;
            }
            cout << "download: " << i << endl;
            return i;
        };
        auto funDownload = [&](std::promise<int> && p) {
            p.set_value(__HeavyWork::SimulateDownload(funDLCallback));
        };



        std::promise<int> p;
        auto f = p.get_future();
        std::thread t(funDownload, std::move(p));
        //dlg.doModal();
        t.join();
        cout << "return value: " << f.get() << endl;
    }

回答by kuroi neko

It all depends on your definition of "simple".

这一切都取决于您对“简单”的定义。

Using futures will certainly do the magic trick in a few lines of C++, but I find it debatable to hiHyman a mechanism that was designed for parallel processing for such a trivial use.

使用期货肯定会在几行 C++ 中实现魔术,但我发现劫持一个专为并行处理而设计的机制来实现这种微不足道的用途是值得商榷的。

futures mostly make sense on multicore CPUS, where they allow a process to launch unsynchronized tasks that will leech computing power from the other cores (leaving aside the fact that finding a set of uncorelated data big enough to be worth the effort is not such a trivial matter either).

futures 主要在多核 CPU 上有意义,它们允许一个进程启动不同步的任务,这些任务将从其他内核汲取计算能力(撇开这样一个事实,即找到一组大到值得付出努力的不相关数据并不是一件容易的事也没关系)。

Using the whole mechanism as a workaround to retrieve a mere int return value is what I call syntax-driven software design. It sits pretty as a showcase for C++11 versatility, but it does hide considerable resource consumption under an icing of syntactic sugar.

使用整个机制作为一种变通方法来检索纯粹的 int 返回值,这就是我所说的语法驱动的软件设计。它很好地展示了 C++11 的多功能性,但它确实在语法糖霜下隐藏了大量的资源消耗。

If not for using other cores as raw power source, what is the point in creating a thread if you don't mean to communicate with it until it's done?
Because if you do, retrieving whatever status from it, be it at termination or anytime else, will be a trivial matter and you will not even think of using futures in the first place.

如果不是使用其他内核作为原始电源,如果您不想在线程完成之前与其进行通信,那么创建线程有什么意义?
因为如果你这样做,从中检索任何状态,无论是在终止时还是在其他任何时候,都将是一件小事,你甚至不会首先考虑使用期货。

Except for the (arguable) convenience of it or the aesthetic appeal, what do these kinds of tricks achieve functionallythat could be considered useful enough to offset the hidden costs?

除了它的(有争议的)便利性或审美吸引力之外,这些类型的技巧在功能上实现了什么,可以被认为足够有用以抵消隐藏成本?

Reading such answers with no proper multitasking background, the new kids on the block might be tempted by using these kind of inefficient mechanisms on a regular basis.
That would only pollute future software with more cases of Schlemiel the Painter's syndrom.

在没有适当的多任务处理背景的情况下阅读这些答案,街区的新孩子可能会因定期使用这些低效机制而受到诱惑。
那只会用更多的施莱米尔画家综合症来污染未来的软件。