如何最好地运行类成员函数并跟踪其在main中的进度?

时间:2014-11-25 21:01:01

标签: c++ multithreading progress

我有一个类,它有一个成员函数,可以打开一个文件,逐行读取并对它做一些事情,然后逐行写入另一个文件。这需要一些时间。

我在一个线程中运行此函数。现在我想显示函数的进度但是从main而不是将代码添加到将显示进度的类函数(printf等)。

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

1 个答案:

答案 0 :(得分:0)

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

首先,我们有一个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;
}

重要提示:此代码不涉及并发性,不要将其用于生产只是一种说法。