指定launch :: async时std :: async不执行

 94Wong_386 发布于 2023-02-04 19:32

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

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

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

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

无需等待呼叫std::future::get().这似乎不是这种情况(使用MSVC 13进行编译).如果这不是由这个语句本身触发的,如果我不关心std::future对象的返回值,应该如何触发?

例:

#include 
#include 
#include 
#include 

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 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;
}

Yakk - Adam .. 9

你必须知道的第一件事情是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::threads 会发生什么,而是由你的特定实现决定.

基于一些快速研究,当MSVC Windows程序离开main的末尾时,线程终止.

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

如果你有一个符合要求的C++ 11编译器,你的尝试async将无法异步,因为它会在销毁std::future它返回的匿名时立即阻止.

最后,请注意,已创建的threads等可能未安排在创建后立即运行.它们如何以及何时运行是不可预测的.

C++ 11并发原语仅仅是原语.他们中的许多人都有古怪的行为,比如如果一个std::thread电话terminate在没有被detach编辑或被join编辑的情况下被破坏,并且async如果你不存储它就会被阻止future.它们可用于简单任务,也可用于编写更高级别的库,但它们不是用户友好的.

1 个回答
  • 你必须知道的第一件事情是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::threads 会发生什么,而是由你的特定实现决定.

    基于一些快速研究,当MSVC Windows程序离开main的末尾时,线程终止.

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

    如果你有一个符合要求的C++ 11编译器,你的尝试async将无法异步,因为它会在销毁std::future它返回的匿名时立即阻止.

    最后,请注意,已创建的threads等可能未安排在创建后立即运行.它们如何以及何时运行是不可预测的.

    C++ 11并发原语仅仅是原语.他们中的许多人都有古怪的行为,比如如果一个std::thread电话terminate在没有被detach编辑或被join编辑的情况下被破坏,并且async如果你不存储它就会被阻止future.它们可用于简单任务,也可用于编写更高级别的库,但它们不是用户友好的.

    2023-02-04 19:35 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有