【问题标题】:Difference in C++11 async behaviour on Mac and LinuxMac 和 Linux 上 C++11 异步行为的差异
【发布时间】:2017-03-03 22:08:45
【问题描述】:

考虑以下 C+11 代码:

#include <chrono>
#include <future>
#include <iostream>
#include <thread>

using namespace std;

int main() {
    auto start = chrono::steady_clock::now();
    auto elapsed = [start](string s) {
        cout << s << (chrono::steady_clock::now() - start).count() << endl;
    };

    elapsed("A ");
    auto fut (async([]() { this_thread::sleep_for(chrono::seconds(2)); }));
    elapsed("B ");
    this_thread::sleep_for(chrono::seconds(1));
    elapsed("C ");
    fut.wait();
    elapsed("D ");
    return 0;
}

Mac 结果

在 macOS Sierra 上使用命令 c++ -std=c++11 -stdlib=libc++ -Wall question.cc -o question 编译上述代码并运行,我得到输出:

A 27186
B 86970
C 1001961755
D 2001585903

这是预期的。到达 AB 花费了最少的时间,等待 1 秒然后到达 C,并等待剩余的 2 秒(1 秒已经过去)到达 D

Mac 编译器是:

$ c++ --version
Apple LLVM version 8.0.0 (clang-800.0.38)
Target: x86_64-apple-darwin16.0.0
Thread model: posix

Linux 结果

在Linux上,我用c++ -std=c++11 -pthread question.cc -o question编译了同样的代码并运行,得到了结果:

A 32423
B 444340
C 1003635793
D 3006121895

Linux 编译器是:

$ c++ --version
c++ (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.

我还在 Linux 上尝试了clang++,LLVM C++ 编译器。结果相同。

为什么在 Linux 上 CD 之间有整整 2 秒的延迟?异步任务不应该在后台运行吗?我是否使用了错误的编译选项?

【问题讨论】:

  • 无法在 Linux 上使用 gcc 6.2 重现。 C 到 D 需要一秒钟。
  • @SamVarshavchik 编译器的区别?
  • 我可以在 Linux 4.4.0-42 上使用 g++ 5.4.0-6ubuntu1~16.04.2 进行复制。介意在 Linux 上发布strace question 的输出吗?
  • std::launch::async 明确设置为所需的策略也会在 Linux 上产生预期的行为。

标签: c++ linux macos c++11 asynchronous


【解决方案1】:

async 可以作为可选参数,如果您想在不同的线程中启动它,或者等到调用.wait 来运行代码。

你选择了“我不在乎”,省略了它。

如果您关心,请在不同的线程中声明您想要它。如果没有,如果他们等到你 .waited 运行它,或者启动一个新线程并在那里运行它,你不应该感到惊讶。在您的情况下,一个编译器使它变得懒惰,另一个将它放在自己的线程中。两者都是标准允许的。

要获得您期望的行为,请将std::launch::async 作为第一个参数传递给std::async


现在,理论上 async 没有被告知如何运行它应该做一些聪明的事情。但是一些编译器说“总是懒惰对我们来说工作更少”(或者总是异步),所以只要你允许它总是懒惰。

这是一个实施质量问题。在这一点上,你不能相信async 对你正在使用的所有 C++11 编译器都很聪明。十年后再回来。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    • 2018-03-20
    • 1970-01-01
    相关资源
    最近更新 更多