C ++ 11 async&未来的产出无序

时间:2017-10-07 08:07:57

标签: c++ c++11

我试图模拟C ++ 11在sleep_for随机时间处理来自其他服务的延迟响应。

// g++ f1.cpp -o f1 -std=c++11 -lpthread
#include <future>
#include <iostream>
#include <vector>
#include <chrono>
#include <thread>
#include <random>
#include <fstream>

using namespace std;

ofstream fout("log.txt");

int twice(int m) {
    random_device rd;
    int isleept = rd() % 100 + 1;
    this_thread::sleep_for(chrono::milliseconds(isleept));
    fout << m << " done with " << isleept << " milliseconds" << endl;
    return 2 * m;
}

int main() {
    vector<future<int> > futs;

    for (int i=0; i<10; i++) {
        futs.push_back(async(twice, i));
    }

    for (auto &e : futs) {
        e.get();
    }

    return 0;
}

当我运行编译文件时,输出文件似乎是无序的:

9 done with 3 milliseconds
8 done with 8 milliseconds
3  done with 32 milliseconds33 milliseconds

3  done with 32 milliseconds33 milliseconds

6 done with 35 milliseconds
7 done with 38 milliseconds
540 milliseconds
2 done with 54 milliseconds
1 done with 65 milliseconds
4 done with 83 milliseconds

我想知道如何改进我的计划?

1 个答案:

答案 0 :(得分:3)

此程序导致数据竞争。也就是说,fout在没有适当锁定的情况下同时从多个线程调用。

我建议添加一些锁定机制。例如,您可以在std::mutex之上使用std::lock_guard添加std::mutex并将输出锁定到日志文件:

std::mutex io_mutex;

int twice(int m) {
    random_device rd;
    int isleept = rd() % 100 + 1;
    this_thread::sleep_for(chrono::milliseconds(isleept));

    std::lock_guard<std::mutex> lock(io_mutex);
    fout << m << " done with " << isleept << " milliseconds" << endl;

    return 2 * m;
}