c++ - std::async 在指定 launch::async 时不执行

标签 c++ multithreading c++11 asynchronous

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

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.

让我觉得我的线程应该立即从这个语句开始:

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返回值 block 直到 std::async完成。

MSVC 的实现没有。这使得他们的 std::async看似用起来比较友好,实际操作起来还是比较棘手的。

然而,作为std::async的行为是根据 std::thread 描述的,我们可以看看当你启动 std::thread 时会发生什么并且无法清理它。结果 std::thread有效分离。一旦你退出 main ,C++ 标准没有指定这样的 std::thread 会发生什么s,将其留给您的特定实现。

根据一些快速研究,当 MSVC windows 程序离开 main 的末尾时,线程将终止。

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

如果您有符合标准的 C++11 编译器,您尝试的 async将无法异步,因为它会在匿名 std::future 销毁后立即阻塞它返回了。

最后,注意启动thread s 等可能不会安排在创建后立即运行。它们运行的​​方式和时间无法预测。

C++11 并发原语仅仅是原语。他们中的许多人都有古怪的行为,比如 std::thread电话 terminate如果它没有被销毁 detach编辑或 join编辑,和async如果你不存储 future,它就会阻塞.它们可用于简单的任务,或用于编写更高级别的库,但它们对用户不友好。

关于c++ - std::async 在指定 launch::async 时不执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21023477/

相关文章:

c++ - 清除 vector 数组的最有效方法

c++ - 虚拟方法作为 Comp 函数进行排序

c++ - 使用 bitset 和共享静态数组将 std::set 专门用于 (u)int8 和 chars 是否合法

c# - 通过同一 session 进行 Telegram 客户端更新和 API 请求

java - Java 中阻塞 main 方法总是不好吗?

c++ - 删除 operator=(Type type) 就够了吗?

c++ - C++中的字符串操作

c# - 等待事件沉默

c++ - C++ 标准是否支持进程?

c++ - 递归生成给定子集大小的所有组合 (C++)