已经在c ++ 11或boost线程监控器?

时间:2014-04-26 13:49:03

标签: c++ c++11 boost

已经在c ++ 11或boost线程监控器? 我需要监视线程执行,当一个因任何原因失败时我需要重新开始。 我在c ++ 11中使用。

1 个答案:

答案 0 :(得分:2)

这取决于线程故障的构成。如果你的意思是它可以退出,你可以打包它:

让我们假装我们有一个长期运行的"任务中途失败的可能性为25%:

int my_processing_task() // this can randomly fail
{
    static const size_t iterations = 1ul << 6;
    static const size_t mtbf       = iterations << 2; // 25% chance of failure
    static auto odds = bind(uniform_int_distribution<size_t>(0, mtbf), mt19937(time(NULL)));

    for(size_t iteration = 0; iteration < iterations; ++iteration)
    {
        // long task
        this_thread::sleep_for(chrono::milliseconds(10));

        // that could fail
        if (odds() == 37) 
            throw my_failure();
    }

    // we succeeded!
    return 42;
}

如果我们想继续运行任务,无论是正常完成还是错误,我们都可以编写监控包装器:

template <typename F> void monitor_task_loop(F f)
{
    while (!shutdown)
    try {
        f();
        ++completions;
    } catch (exception const& e)
    {
        std::cout << "handling: '" << e.what() << "'\n";
        ++failures;
    }
    std::cout << "shutdown requested\n";
}

在这种情况下,我随机认为计算常规完成次数和失败次数会很好。 shutdown标志使线程可以关闭:

auto timeout = async(launch::async, []{ this_thread::sleep_for(chrono::seconds(3)); shutdown = true; });
monitor_task_loop(my_processing_task);

将运行任务监控循环约3秒。运行三个监视我们任务的后台线程的演示是 Live On Coliru

添加了a c++03 version using Boost Live On Coliru

此版本仅使用标准的c ++ 11功能。

#include <thread>
#include <future>
#include <iostream>
#include <random>

using namespace std;

struct my_failure : virtual std::exception {
    char const* what() const noexcept { return "the thread failed randomly"; }
};

int my_processing_task() // this can randomly fail
{
    static const size_t iterations = 1ul << 4;
    static const size_t mtbf       = iterations << 2; // 25% chance of failure
    static auto odds = bind(uniform_int_distribution<size_t>(0, mtbf), mt19937(time(NULL)));

    for(size_t iteration = 0; iteration < iterations; ++iteration)
    {
        // long task
        this_thread::sleep_for(chrono::milliseconds(10));

        // that could fail
        if (odds() == 37) 
            throw my_failure();
    }

    // we succeeded!
    return 42;
}

std::atomic_bool shutdown(false);
std::atomic_size_t failures(0), completions(0);

template <typename F> void monitor_task_loop(F f)
{
    while (!shutdown)
    try {
        f();
        ++completions;
    } catch (exception const& e)
    {
        std::cout << "handling: '" << e.what() << "'\n";
        ++failures;
    }
    std::cout << "shutdown requested\n";
}

int main()
{
    auto monitor = [] { monitor_task_loop(my_processing_task); };
    thread t1(monitor), t2(monitor), t3(monitor);

    this_thread::sleep_for(chrono::seconds(3));
    shutdown = true;

    t1.join();
    t2.join();
    t3.join();

    std::cout << "completions: " << completions << ", failures: " << failures << "\n";
}