【问题标题】:How best to run a class member function and track its progress in main?如何最好地运行类成员函数并在 main 中跟踪其进度?
【发布时间】:2014-11-25 21:01:01
【问题描述】:

我有一个类,它有一个成员函数,它打开一个文件,逐行读取并对其执行一些操作,然后逐行写入另一个文件。这需要一些时间。

我在一个线程中运行这个函数。现在我想显示函数的进度,但是从 main 开始,而不向类函数添加代码来显示进度(printf 等)。

这样我可以在 windows 或 linux 中运行该类,但在特定操作系统的 main 中使用不同的进度条代码。

【问题讨论】:

  • 某种回调应该是最合适的。
  • 我建议你使用两个线程都可见的volatile变量来存储函数的进度。
  • 你能举一个代码中的小例子吗?非常感谢

标签: c++ multithreading progress


【解决方案1】:

我赞成@πάντα ῥεῖ(你怎么写!?)的想法。

首先,我们有 abstract_sink 一个结构,它将充当我们所有接收器的接口。

struct abstract_sink {
    virtual void on_progress_inc(int progress) = 0;
};

两个示例接收器:

struct my_sink : abstract_sink {
    void on_progress_inc(int progress) {
        std::cout << "The progress: " << progress << "%" << std::endl;
    }
};

struct my_another_sink : abstract_sink {
    void on_progress_inc(int progress) {
        std::cout << "The progress: " << progress << " --- " << std::endl;
    }
};

最后会实现一个仿函数(参见:C++ Functors - and their uses),这个仿函数代替你的成员函数。

template<typename Sink>
struct process_file_functor
{
    // Constructor.
    process_file_functor(Sink &sink)
    {
        m_sink = std::make_shared<Sink>(sink);
    }

    void operator()(std::string infile, std::string outfile)
    {
        std::fstream inf(infile);
        std::fstream out(outfile);


        int total_lines = std::count(std::istreambuf_iterator<char>(inf), std::istreambuf_iterator<char>(), '\n');
        inf.seekg(0);   
        int progress = 0;

        for (std::string line; std::getline(inf, line); )
        {
            /*
                Here you will do what you have to do and in every iteration
                you will compute progress = 100 * lines_processed / total_lines and call...
            */
            progress++;
            m_sink->on_progress_inc(100 * progress/total_lines); // Here you notify the progress.
        }
    }

    std::shared_ptr<Sink> m_sink;
};

使用示例:

#include <iostream>
#include <fstream>
#include <memory>
#include <string>
#include <thread>

int main(int argc, char *argv[])
{

    my_sink ms;
    my_another_sink mas;

    process_file_functor<my_sink> pfile(ms);
    process_file_functor<my_another_sink> pfile1(mas);

    std::thread t1(pfile, "data1.txt", "data2.txt");
    std::thread t2(pfile1, "data1.txt", "data2.txt");

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

    return 0;
}

重要提示:此代码不处理并发,不要将其用于生产只是说明性的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 2018-12-28
    • 2015-09-03
    相关资源
    最近更新 更多