当指定launch :: async时,std :: async不会执行

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

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

让我觉得我的线程应该立即开始这个声明:

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

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

例:

#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标准。

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

MSVC的实施没有。 这使得他们的std::async看起来更友好,但实际上它非常复杂。

然而,由于std::async的行为是用std::thread来描述的,我们可以看看当你启动一个std::thread并且无法清理它时会发生什么。 生成的std::thread被有效地分离。 一旦你退出main ,C ++标准并没有说明这样的std::thread会发生什么,而是将它留给你的特定实现。

基于一些快速的研究,当一个MSVC窗口程序结束时,线程被终止。

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

如果你有一个符合C ++ 11的编译器,你尝试的async将不会是异步的,因为它会在它返回的匿名std::future被破坏时立即阻塞。

最后,请注意,启动的thread等可能不会安排在创建后立即运行。 他们如何以及何时运行是不可预测的。

C ++ 11并发原语仅仅是原语。 他们中的许多人都具有古怪的行为,如std::thread调用terminate如果它被销毁而未被detachjoin ,以及async的倾向,如果你不存储future 。 它们可以用于简单的任务,或用于编写更高级别的库,但它们不是用户友好的。


我不熟悉C ++ 11,但AFAIK每个程序都有一个主线程,它是main()函数执行的线程。 当该线程的执行完成时,程序将与其所有线程一起完成。 如果你想要你的主线程等待其他线程,使用必须使用类似的东西

在pthread_join

在Linux环境下(如果您手动创建线程)或完全

的std ::未来::得到()

在这个特定的情况下。

退出main会杀死你的线程,在你的情况下可能会阻止你启动线程

链接地址: http://www.djcxy.com/p/5207.html

上一篇: std::async not executing when specifying launch::async

下一篇: Windows setevent processing