2

I have a function that shoud run in a controlled amount of time. But this function uses pcl::StatisticalOutlierRemoval and i didn't find any reasonable way to cancel the this function other than killing the thread arbitrarily.

I have something like this:

void cloud_filtering(pcl::PointCloud<pcl::PointXYZRGB>::SharedPtr pcl_unfilt, pcl::PointCloud<pcl::PointXYZRGB>::SharedPtr pcl_filt) const{

      // do something

      pcl::StatisticalOutlierRemoval<pcl::PointXYZRGB> sor;
      sor.setInputCloud(*pcl_unfilt);
      sor.setMeanK(50);
      sor.setStddevMulThresh(1.0);
      sor.filter(*pcl_filt);

      // do something

}

This function is executed by an independent thread that should have some timeout. The thread is launched using std::async and the completion is checked using the returned future.

auto future = std::async(
      std::launch::async,
      &cloud_filtering,this,pcl_unfilt,pcl_filt
)

Usually, this function is executed pretty fast, but not always, and I don't really need all the responses (It depends on the sampled input of the function). So what I want to do is, if the function takes more than a given timeout it gets safely canceled so I can launch a new thread with other samples.

By safely canceled I mean avoid memory leaks or zombie threads.

  • I am not sure I understand what you try to do, or want to know. `StatisticalOutlierRemoval` will run until it is finished. It has no way to cancel halfway through because why would you? Usually you want/need the results of the filter? If you perhaps describe in more detail what your desired goal is? – IBitMyBytes Apr 22 '23 at 07:56
  • Thanks for your reply @IBitMyBytes. Usually, this function is executed pretty fast, but not always, and I don't really need all the responses (It depends on the sampled input of the function). So what I want to do is, if the function takes more than a given timeout it gets safely canceled so I can launch a new thread with other samples. By safely canceled I mean avoid memory leaks or zombie threads – Lucyanno Frota Apr 22 '23 at 13:44

1 Answers1

1
#include <future>
#include <chrono>

void cloud_filtering(pcl::PointCloud<pcl::PointXYZRGB>::SharedPtr pcl_unfilt, pcl::PointCloud<pcl::PointXYZRGB>::SharedPtr pcl_filt, std::promise<void>&& promise) const{
    // do something
    
    pcl::StatisticalOutlierRemoval<pcl::PointXYZRGB> sor;
    sor.setInputCloud(*pcl_unfilt);
    sor.setMeanK(50);
    sor.setStddevMulThresh(1.0);
    sor.filter(*pcl_filt);

    // do something

    promise.set_value(); // signal completion
}

// function to call with a timeout
bool cloud_filtering_with_timeout(pcl::PointCloud<pcl::PointXYZRGB>::SharedPtr pcl_unfilt, pcl::PointCloud<pcl::PointXYZRGB>::SharedPtr pcl_filt, int timeout_ms) {
    std::promise<void> promise;
    auto future = promise.get_future();
    auto task = std::async(std::launch::async, &cloud_filtering, this, pcl_unfilt, pcl_filt, std::move(promise));
    bool completed = false;
    if (future.wait_for(std::chrono::milliseconds(timeout_ms)) == std::future_status::timeout) {
        // timeout occurred, cancel task
        task.get(); // this will call std::terminate() if the task is still running
        completed = false;
    } else {
        completed = true;
    }
    return completed;
}
  • cloud_filtering_with_timeout takes input point clouds + timeout in milliseconds -- returns boolean value(whether the function completed before the timeout or not)

std::promise signals cloud_filtering completion -- std::future waits for completion with timeout(timeout occurs before function completes -- task.get() call will cancel the task - throws std::future_error -- will be caught + ignored by std::async)

PS. isn't a clean way to cancel pcl::StatisticalOutlierRemoval but should avoid memory leaks and zombie threads

Lemonina
  • 712
  • 2
  • 14