Mac和Linux上C 11异步行为的差异

考虑以下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结果

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

A 27186
B 86970
C 1001961755
D 2001585903

这是预料之中的.到达A和B只需要很短的时间,等待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问题编译了相同的代码并运行,得到了结果:

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,即LLVM C编译器.结果相同.

Q

为什么Linux上的C和D之间存在完全2秒的延迟?是不是异步任务应该在后台运行?我使用错误的编译选项吗?

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

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

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

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

现在,理论上async没有被告知如何运行它应该做一些聪明的事情.但是有些编译器喋喋不休并且说“总是做懒惰对我们来说不那么有用”(或者总是异步),所以每当你放弃它时总是很懒.

这是一个实施质量问题.此时,您不能相信async在您正在使用的所有C 11编译器上都是智能的.十年后回来.

相关文章
相关标签/搜索