已经在c++11或boost线程监视器了吗?

时间:2021-12-13 21:02:40

Is already in c++11 or boost thread monitor ? I need to monitor thread execution and when one fails for any reason I need to start again. I am using in c++11.

已经在c++11或boost线程监视器了吗?我需要监控线程的执行情况,当其中一个出现故障时,我需要重新开始。我用的是c++11。

1 个解决方案

#1


2  

This depends on what constitutes a thread failure. If you mean it could exit, you can package it up:

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

Let's pretend we have a "long-running" task with a 25% chance of failing midway:

让我们假设我们有一个“长时间运行”的任务,有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;
}

If we want to keep running the task, regardless of whether it completed normally, or with an error, we can write a monitoring wrapper:

如果我们想继续运行任务,不管它是否正常完成,或者有错误,我们可以编写一个监控包装器:

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";
}

In this case, I randomly thought it would be nice to count the number of regular completions, and the number of failures. The shutdown flag enables the thread to be shutdown:

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

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

Will run the task montoring loop for ~3 seconds. A demonstration running three background threads monitoring our task is Live On Coliru.

将运行任务montoring循环3秒。一个运行三个后台线程监控我们任务的演示是基于Coliru的。

Added a c++03 version using Boost Live On Coliru.

在Coliru上增加了一个c++03版本。

This version uses only standard c++11 features.

这个版本只使用标准的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";
}

#1


2  

This depends on what constitutes a thread failure. If you mean it could exit, you can package it up:

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

Let's pretend we have a "long-running" task with a 25% chance of failing midway:

让我们假设我们有一个“长时间运行”的任务,有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;
}

If we want to keep running the task, regardless of whether it completed normally, or with an error, we can write a monitoring wrapper:

如果我们想继续运行任务,不管它是否正常完成,或者有错误,我们可以编写一个监控包装器:

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";
}

In this case, I randomly thought it would be nice to count the number of regular completions, and the number of failures. The shutdown flag enables the thread to be shutdown:

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

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

Will run the task montoring loop for ~3 seconds. A demonstration running three background threads monitoring our task is Live On Coliru.

将运行任务montoring循环3秒。一个运行三个后台线程监控我们任务的演示是基于Coliru的。

Added a c++03 version using Boost Live On Coliru.

在Coliru上增加了一个c++03版本。

This version uses only standard c++11 features.

这个版本只使用标准的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";
}