当指定launch :: async时,std :: async不执行 [英] std::async not executing when specifying launch::async

查看:474
本文介绍了当指定launch :: async时,std :: async不执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许我错过了在C ++ 11新的 std :: async 的正确用法,但这个语句(在 cppreference.com ):

Maybe I'm missing the correct usage of the new std::async in C++11, however this statement (over at cppreference.com):


如果设置了async标志(即policy& std :: launch :: async!= 0),则async在单独的执行线程上执行函数f,就好像由std :: thread(f,args ...),除了如果函数f返回一个值或抛出一个异常,它被存储在可通过std :: future访问的共享状态,async返回调用者。

If the async flag is set (i.e. policy & std::launch::async != 0), then async executes the function f on a separate thread of execution as if spawned by std::thread(f, args...), except that if the function f returns a value or throws an exception, it is stored in the shared state accessible through the std::future that async returns to the caller.

使我认为我的线程应该立即用这个语句开始:

Makes me think that my thread should start immediately with this statement:

std::async(std::launch::async, MyFunctionObject());

无需等待调用 std :: future :: get )。这似乎不是这样(使用MSVC 13编译)。如果这不是由这个语句本身触发的,如果我不在乎 std :: future 对象的返回值,那么应该如何触发呢?

Without having to wait for calling the std::future::get(). This seems to not be the case (compiling with MSVC 13). If this is not triggered by this statement itself, how should this get triggered if I don't care about the return value of the std::future object?

示例:

#include <thread>
#include <iostream>
#include <array>
#include <future>

static std::mutex write_mutex;

class Cpp11Threads {
public:
    // Function operator for Function-Object
    void operator()() {
        const int num_threads = 50;

        // Static std array
        std::array<std::thread*, num_threads> worker_threads;

        // Range based
        for (std::thread*& thread : worker_threads) {

            // Lambda expression
            thread = new std::thread(
                [] {
                    static int i = 0;
                    write_mutex.lock();
                    std::cout << "Hello, I am happy Std thread #" << i++ << std::endl;
                    write_mutex.unlock();
                });
        }

        for (std::thread*& thread : worker_threads) {
            thread->join();
            delete thread;

            // nullptr instead of NULL
            thread = nullptr;
        }
    }
};

int main() {
    std::async(std::launch::async, Cpp11Threads());
    return 0;
}


推荐答案

知道是MSVC std :: async 不符合C ++ 11标准

The first thing you have to know is that MSVC std::async does not conform to the C++11 standard.

在C ++ 11标准下, std :: async std :: future 返回值块直到 std :: async 完成。

Under the C++11 standard, std::async's std::future return value blocks until the std::async completes.

MSVC的实现不会。这使得他们的 std :: async 看起来更友好,但在实践中它是相当棘手。

MSVC's implementation does not. This makes their std::async seemingly more friendly to use, but in practice it is quite tricky.

但是,因为 std :: async 的行为被描述为 std :: thread ,我们可以看看当你启动 std :: thread 并且无法清理它时会发生。生成的 std :: thread 有效地分离。一旦你退出 main ,C ++标准不指定 std :: thread

However, as std::async's behavior is described in terms of std::thread, we can look at what happens when you kick off a std::thread and fail to clean it up. The resulting std::thread is effectively detached. Once you exit main, the C++ standard does not specify what happens to such std::threads, leaving it up to your particular implementation.

根据一些快速研究,当MSVC Windows程序离开main结束时,线程被终止。

Based off some quick research, when a MSVC windows program goes off the end of main, the threads are terminated.

简而言之,您的程序需要与以某种方式启动的线程重新同步,以便他们可以完成其任务,并防止主程序退出 main 。一个简单的方法是存储从 async 任务返回的 std :: future

In short, your program needs to resynchronize with the threads you launched in some way or another, so that they can complete their tasks, and prevent the main program from exiting main. An easy way to do that is to store the returned std::future from your async task, and wait on it before main exits.

如果你有一个符合C ++ 11编译器,您的尝试 async 将不能是异步的,因为它将立即阻止匿名 std :: future 它返回。

If you had a conforming C++11 compiler, your attempted async would fail to be asynchronous, as it would block immediately upon the destruction of the anonymous std::future it returned.

最后,注意启动线程计划在创建后立即运行。它们的运行方式和时间是不可预测的。

Finally, note that launched threads and the like may not be scheduled to run immediately after creation. How and when they run is not predictable.

C ++ 11并发原语只是原语。它们中的许多具有古怪的行为,例如 std :: thread 调用 terminate 分离 ed或加入 ed和 async 如果您不存储 future ,则阻止。它们可以用于简单的任务,或用于编写更高级别的库,但它们不是用户友好的。

The C++11 concurrency primitives are merely primitives. Many of them have quirky behavior, like the fact that a std::thread calls terminate if it is destroyed without being detached or joined, and async's tendency to block if you don't store the future. They can be used for simple tasks, or for writing higher level libraries, but they are not user friendly.

这篇关于当指定launch :: async时,std :: async不执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆