c++ 11在Mac和Linux上异步行为的差异

Difference in C++11 async behaviour on Mac and Linux

本文关键字:异步 Mac Linux c++      更新时间:2023-10-16

考虑以下c++代码:

#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++编译器。相同的结果。

<标题> Q

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

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

你省略了"I do not care"。

如果你关心,说明你想在不同的线程中。如果没有,如果它们一直等到您设置了.wait才运行它,或者启动一个新线程并在那里运行它,您不应该感到惊讶。在您的情况下,一个编译器使它变得懒惰,另一个将它放在自己的线程中。

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


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

这是一个实现质量问题。在这一点上,您不能相信async在您正在使用的所有c++ 11编译器上都是智能的。十年后再来。