PCL_PCLVisualizer在多线程中的使用问题(viewer spinOnce crash)

25 篇文章 0 订阅
13 篇文章 20 订阅

问题描述:

  • 使用多线程进行点云的实时重建, 在主线程中创建 PCLVisualizer 对象指针(即使智能指针boost::shared_ptr),传入子线程中进行显示(viewer->spinOnce(100),)结果crash
//主线程中:
	typedef boost::shared_ptr<pcl::visualization::PCLVisualizer> PViewer;

	//定义 PCLVisualizer
    PViewer pViewer (new pcl::visualization::PCLVisualizer ("ReconstructionViewer"));
    pViewer->initCameraParameters();
    pViewer->setCameraPosition(0, -15, -15,
								0,  0,  5,
								0, -1,  0);
    pViewer->addCoordinateSystem (0.5, 0, 0, 0);
	
	// 声明一个类Reconstruction,使用PCLVisualizer, 
	// 将 PCLVisualizer对象pViewer 传入Reconstruction构造函数,赋值给其成员对象 mpViewer
	mpReconstructor = new Reconstruction(pCloud, pViewer, pSock);
	 
	//启动子线程线程 Run, 在Run中使用 mpViewer(即在主线程中定义的PCLVisualizer对象pViewer)
	mptReconstruction = new thread(&Reconstruction::Run,mpReconstructor);
	
//子线程:
    void Reconstruction::Run()
    {
        //...
	    //结果调用下面两个函数时 crash
	    mpViewer->setCameraPosition(....);
	    mpViewer->spinOnce(100);
        //...
    }

原因分析:

 哪个个线程创建 PCLVisualizer 对象,那个线程有其使用权,传递给其他线程则不能使用。 一定要看库的说明

此类不能跨多个线程使用。 仅从创建它们的同一线程中调用此类对象的函数! 一些方法,例如 addPointCloud,如果从其他线程调用会崩溃。

namespace pcl
{
  template <typename T> class PointCloud;
  template <typename T> class PlanarPolygon;

  namespace visualization
  {
    /** \brief PCL Visualizer main class.
      * \author Radu B. Rusu
      * \ingroup visualization
      * \note This class can NOT be used across multiple threads. Only call functions of objects of this class
      * from the same thread that they were created in! Some methods, e.g. addPointCloud, will crash if called
      * from other threads.
      */
    //此类不能跨多个线程使用。 仅从创建它们的同一线程中调用此类对象的函数! 一些方法,例如 addPointCloud,如果从其他线程调用会崩溃。
    class PCL_EXPORTS PCLVisualizer
    {
       //...
    }
 }
}

其他参考:

I want to have a class which contain a visualizer on a cloud point. here is my code:

class my_vis
{
      void vis_func ()
    {
        pcl::visualization::PCLVisualizer *vis ;
        vis = new pcl::visualization::PCLVisualizer("octree viewer");
        // this "vis" is just used in this function and no other place
    }

    void execute(){
        //Start visualizer in a thread
        boost::thread* visThread = new boost::thread(boost::bind(&my_vis::vis_func, this));
        // bla bla
    }
}
int main ()
{    
    my_vis vis1();
    vis1.execute();
    my_vis vis2();
    vis2.execute();
    std::getchar();
    return 0 ;
}
now I have a class of visualizers which can be instantiated in "main". when I made just one instance from the class "my_vis" every thing is OK when the program runs. But I need two or more instances. and when I initialize more than one instance, an error occured: BLOCK_TYPE_IS_VALID I think that it is because of using threads. But threading is necessary in my project.

Would you please help me? Thanks a lot for your patient and help :)

P.S. I am using PCL 1.7
After two days, I finally solve this.

I pay attention to the constructor of pcl::visualization::PCLVisualizer and also "SpinOnce" function and I recognize that if you put a static lock, so that just one thread among multiple objects can access these functions, then the problem will be solved.

previously, I put non static locks on these function, and as you know local locks just work in the same object which they are created in (Not the whole objects which are instantiated from a class). So I defined a static lock in my_vis class:

    private static boost::mutex vis_mutex; 
    boost::mutex my_vis::vis_mutex; //storage for static lock 
and replace "vis->spinOnce(1)" with

    { 
            boost::mutex::scoped_lock vis_lock(vis_mutex); 
            vis->spinOnce (); 
    } 
I still think that it is not a permanent solution, and this bug is better to be solved by pcl developers :)

感言:

  • 写bug,20%的时间就写完了,找bug,需要80%的时间;
  • 当你找bug找到自己快要crash时,答案就快要出现了。
  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

惊鸿一博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值