ошибка сегментации при использовании icp с пулом потоков - PullRequest
0 голосов
/ 29 сентября 2018

Пул потоков получен из https://github.com/progschj/ThreadPool. Пример кода icp с многопоточностью показан ниже:

#include <iostream>
#include <vector>
#include <chrono>

#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/registration/icp.h>

#include "ThreadPool.h" 

void foo(pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp) { 
  pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp_(icp); 
  pcl::PointCloud<pcl::PointXYZ> cloud; 
  std::cout << &icp << std::endl; 
  icp_.align(cloud); 
  std::this_thread::sleep_for(std::chrono::seconds(1)); 
} 

int main() { 

  pcl::PointCloud<pcl::PointXYZ>::Ptr map(new pcl::PointCloud<pcl::PointXYZ>); 

  map->width = 10; 
  map->height = 1; 
  map->is_dense = false; 
  map->points.resize(10); 

  for (auto &point:map->points) { 
    point.x = (RAND_MAX / 2 - rand()) / (RAND_MAX + 1.0f) * 10; 
    point.y = (RAND_MAX / 2 - rand()) / (RAND_MAX + 1.0f) * 10; 
    point.z = (RAND_MAX / 2 - rand()) / (RAND_MAX + 1.0f) * 2; 
  } 
  pcl::PointCloud<pcl::PointXYZ>::Ptr 
      lidar(new pcl::PointCloud<pcl::PointXYZ>); 
  *lidar = *map; 

  pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp; 
  icp.setInputSource(lidar); 
  icp.setInputTarget(map); 

  ThreadPool pool(3); 
  std::vector<std::future<void> > results; 

  for (int i = 0; i < 10; ++i) { 
    results.emplace_back( 
        pool.enqueue(foo, icp) 
    ); 
  } 

  for (auto &&result: results) 
    result.get(); 
  std::cout << std::endl; 

  return 0; 
} 

Я распечатываю адрес объекта icp в fooфункция, и я получил результат, показанный ниже:

0x7f387345b9d0 
0x7f3872c5a9d0 
0x7f38724599d0

Затем я получил ошибку сегментации.Поэтому, если я объявлю три потока, четвертое задание застрянет.

Однако, если я изменю функцию foo, как показано ниже, все будет хорошо

void foo(pcl::IterativeClosestPoint<pcl::PointXYZ,pcl::PointXYZ> icp){ 
  pcl::IterativeClosestPoint<pcl::PointXYZ,pcl::PointXYZ> icp_; 
  icp_.setInputSource(icp.getInputSource()); 
  icp_.setInputTarget(icp.getInputTarget()); 
  pcl::PointCloud<pcl::PointXYZ> cloud; 
  icp_.align(cloud); 
  std::this_thread::sleep_for(std::chrono::seconds(1)); 
} 

Но я хочу установитьпараметр icp вне функции foo, а затем сделайте копию icp в функции foo.Поэтому мне не нужно изменять параметр внутри задачи потока foo.

Я не знаком с базовой архитектурой памяти, я пытаюсь использовать valgrind, но понятия не имею.

...