英特尔TBB,parallel_pipeline,在阶段之间传递const char *时出错

时间:2018-01-26 00:30:05

标签: c++ string char ifstream tbb

我有以下管道:

parallel_pipeline(20,
       make_filter<void,const char*>(
          filter::serial,
          [&](flow_control& fc)->const char*
          {
            getline(fe,orden_fichero);
            if(fe.eof())
            {
              fc.stop(); // stop processing
              return nullptr;
            }
            else
            {
              return orden_fichero.c_str();
            }
          }
        ) &
      make_filter<const char*,void>(
          filter::parallel,
          [&](const char* p){

              string orden(p);
          }
        )
      );

之前,当我使用字符串而不是const char*时,第一次返回orden_fichero而没有转换为const char*,程序运行良好,但速度很慢。我已经看到使用const char*可以提高程序的性能,但是这样一些行在管道的第二阶段没有正确接收(有些行缺少字符)例如一个10M行文件,26行对应orden字符串,大小为0,9,大小在2到35之间,其余所有都正确接收(顺序变量有36个字符或更多)

  • 我怎样才能正确地从firts管道中找到第二个的char char *?

  • 有一些方法可以在英特尔TBB中读取文件,以便并行地对每一行进行操作,并以更好的方式将结果保存到向量中,而不是我想要做的那个? / p>

1 个答案:

答案 0 :(得分:0)

问题是你首先要返回orden_fichero的副本(我猜是std :: string)。使用当前代码,您将返回指向orden_fichero内部数据的指针,因此当线程1(第一个管道阶段)从文件中读取一行并将其存储在orden_fichero中时,数据已损坏,它从线程2(第二个流水线阶段)读取。

显示了如何正确返回c字符串的一些方法here(特别是我建议使用版本2)。但是,这将再次分配大量内存,并且很可能与返回std :: string几乎一样低效。

您可以尝试在parallel_pipeline之外创建一个新字符串,将orden_fichero的c_str复制到该字符串中,然后将指针返回到该字符串。但我不确定这会正常工作......

std::string another_string;
parallel_pipeline(20,
       make_filter<void,const char*>(
          filter::serial,
          [&](flow_control& fc)->const char*
          {
            getline(fe,orden_fichero);
            if(fe.eof())
            {
              fc.stop(); // stop processing
              return nullptr;
            }
            else
            {
              another_string = orden_fichero;
              return another_string.c_str();
            }
          }
        ) &
      make_filter<const char*,void>(
          filter::parallel,
          [&](const char* p){

              string orden(p);
          }
        )
      );

因此,在通过orden_fichero将数据读入getline时,可以安全地使用another_string。但正如我所说,我不确定这是否会正常工作,因为第二个管道阶段的线程可能会在const char* p被复制到orden之前被抢占,并且第一阶段的线程可能会被抢占然后覆盖another_string并使p无效。您可以尝试使用互斥锁保护another_string,但我想这会再次减慢速度。