C++ 具有成员函数和带参数的构造函数的多线程处理

C++ 具有成员函数和带参数的构造函数的多线程处理,c++,c++11,shared-ptr,boost-thread,C++,C++11,Shared Ptr,Boost Thread,在这种情况下,我需要实例化boost::threads向量来解决以下问题: 我有一个名为Instrument的类来保存符号信息,如下所示: class Instrument { public: Instrument(StringVector symbols, int i); virtual ~Instrument(); const Instrument& operator= (const Instrument& inst) {

在这种情况下,我需要实例化boost::threads向量来解决以下问题:

我有一个名为Instrument的类来保存符号信息,如下所示:

class Instrument
{
    public:
    Instrument(StringVector symbols, int i);
    virtual ~Instrument();
    const Instrument& operator= (const Instrument& inst)
    {
        return *this;
    }
    String GetSymbol() { return Symbol_; }
    LongToSymbolInfoPairVector GetTS() { return TS_; }
    bool OrganiseData(TimeToSymbolsInfoPairVector& input, int i);
    static int getRandomNumber(const int low, const int high);
    static double getProbability();
    bool ConstructNewTimeSeries(const int low, const int high);
    bool ReconstructTimeSeries(TimeToSymbolsInfoPairVector& reconstructeddata, int i);

private:
    LongToSymbolInfoPairVector TS_;
    String Symbol_;
    const int checkWindow_;
    String start_, end_;
    long numberofsecsinaday_;
    static std::default_random_engine generator_;
};
此类的对象数量与符号数量相同。这些符号应在另一个类别分析中访问,以便进一步工作,其建造师接受上述仪器类别的向量,如下所示

class Analysis
{
public:
    Analysis(std::vector<Instrument>::iterator start, std::vector<Instrument>::iterator end);
    virtual ~Analysis();
    bool buildNewTimeSeries(TimeToSymbolsInfoPairVector& reconstructeddata);
    bool printData(TimeToSymbolsInfoPairVector& reconstructeddata);

private:
    std::vector<Instrument> Instruments_;
};
类分析
{
公众:
分析(std::vector::迭代器开始,std::vector::迭代器结束);
虚拟分析();
bool buildNewTimeSeries(TimeToSymbolsInfoPairVector和重构数据);
bool打印数据(TimeToSymbols InfoPairVector和重建数据);
私人:
std::矢量仪器;
};
现在我想对这个过程进行多线程处理,这样我就可以将每个线程分离出来,比如说7个符号,然后生成4个线程

以下是更新后的主要内容

std::vector<Instrument>::iterator block_start = Instruments.begin();
int first = 0, last = 0;
for (unsigned long i=0; i<MAX_THREADS; i++)
{
    std::vector<Instrument>::iterator block_end = block_start;
    std::advance(block_end, block_size);
    last = (i+1)*block_size;
    Analysis* analyzed = new Analysis(block_start, block_end /*first, last*/);
    analyzed->setData(output, first, last);
    threads.push_back(std::thread(std::bind(&Analysis::buildNewTimeSeries, std::ref(*analyzed))));
    block_start = block_end;
    first = last;        
}

for (int i=0; i<MAX_THREADS; i++)
{
    (threads[i]).join();
}
std::vector::迭代器块_start=Instruments.begin();
int first=0,last=0;
for(无符号长i=0;isetData(输出、第一个、最后一个);
threads.push_back(std::thread(std::bind(&Analysis::buildNewTimeSeries,std::ref(*analysisd));
块开始=块结束;
第一个=最后一个;
}

对于(int i=0;i),最好使用一种资源分配向量(如:在UR case中:向量)的方法来减少有限的线程数,这是通过使用一个叫做“强> THealthCuths/Stult>的多线程设计范例。C++中没有标准的线程池,因此您可能需要自己构建一个(或者使用开源库)。。您可以在此处查看许多优秀的开源实现之一:-

现在,我不打算使用线程池,只会给你一些建议,帮助你在不修改核心功能/想法的情况下解决问题

大体上,您使用new动态创建向量,并通过取消引用指针来传递向量的引用。Analysis*analysisd=new。我知道您的想法是在main和thread函数中使用相同的向量分析*。我认为这不是一个好的设计。有更好的方法去做吧

不要使用std::thread,而是使用std::async。std::async创建任务,而不是线程。std::async创建的任务与线程相反。通过使用async使用任务有许多优点。我不想通过描述线程/任务来回答这个问题。但是,任务的一个主要优点是它可以让您将任务中的值(称为未来)返回到主功能

否要重写主函数async,请按如下方式调整代码

  • 不要使用new动态创建向量,而只是创建一个 本地向量,只需使用std::move to the task移动向量 在调用异步时
  • 修改Analysis::buildNewTimeSeries以接受右值引用
  • 使用右值向量编写用于分析的构造函数
  • 然后,任务将在本地修改此向量,然后 将此向量返回到main函数
  • 调用async时,存储async的返回值 在向量中调用>
  • 使用async启动所有任务后,您可以对这个未来向量的每个元素调用.get()
  • 此.get()方法将返回从中修改并返回的向量 线
  • 将这些返回的向量合并到最终结果向量中

通过将向量从main移动到thread,然后返回,您只允许一个所有者以独占方式访问向量。因此,在向量移动到thread之后,您无法从main访问向量。这与您的实现不同,在您的实现中,main函数和thread函数都可以访问新创建的向量这是通过引用线程来传递的。

如果有,
input2
工具之间的关系是什么?它们的大小是否相同?我这样问是因为您从前者计算
block\u size
,但使用它将迭代器推进到后者。您将指向局部变量的指针向下传递到线程。这里有很有可能在线程完成之前(甚至可能在它启动之前)该变量会被销毁。您的程序通过竞争条件显示未定义的行为。TimeToSymbols InfoPairVector input2=csvParser.getRawDataVector();其中csvParser是另一个具有以下骨架的类解析器的对象。类解析器{public:Parser();virtual~Parser();bool ParseCsv(std::string filename);TimeToSymbolsInfoPairVector getRawDataVector(){return rawdata_;}StringVector getSymbolName(){return symbolname_;}bool printData();专用:符号sym;字符串向量symbolname;时间到符号InfoPairVector原始数据;IterStringVector iterFields;correct@IgorTandetnik你能帮我重写一个main来满足这个需求吗?我已经经历了数百次堆栈溢出,尝试了很多方法,但是没有一个简单的解决方案。你需要确保
分析的实例在线程使用它的时候一直存在。例如,通过分配它在堆上。感谢@Laks的详细解释。虽然上面的解释很有意义,但这并不能完全满足我的目的,因为我希望延迟尽可能低。使用异步,从内核切换到操作系统再切换回来的过程将增加更多的时间。我只使用线程进行排序并不重要异步的美妙之处在于,异步可以同时用作阻塞和非阻塞。下面的文章可能会更好地解释这些概念